Domanda

A volte ho bisogno di estrarre rapidamente alcuni dati arbitrari da file XML per inserirli in un formato CSV.Quali sono le migliori pratiche per farlo nel terminale Unix?Mi piacerebbe alcuni esempi di codice, quindi ad esempio come posso risolvere il seguente problema?

Esempio di input XML:

<root>
<myel name="Foo" />
<myel name="Bar" />
</root>

Il mio output CSV desiderato:

Foo,
Bar,
È stato utile?

Soluzione

Se desideri solo gli attributi del nome di qualsiasi elemento, ecco una soluzione rapida ma incompleta.

(Il testo di esempio è nel file esempio)

Esempio "Nome" grep | tagliare -d "" "-f2,2 | xargs -i {} echo" {}, "

Altri suggerimenti

La risposta di Pietro è corretto, ma restituisce un avanzamento riga finale.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text"/>
  <xsl:template match="root">
    <xsl:for-each select="myel">
      <xsl:value-of select="@name"/>
      <xsl:text>,</xsl:text>
      <xsl:if test="not(position() = last())">
        <xsl:text>&#xA;</xsl:text>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Basta eseguire ad es.

xsltproc stylesheet.xsl source.xml

per generare i risultati CSV nell'output standard.

Utilizzare un processore XSLT da riga di comando come xsltproc, sassone O xalan per analizzare l'XML e generare CSV.Ecco un esempio, che nel tuo caso è il foglio di stile:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

    <xsl:template match="root">
        <xsl:apply-templates select="myel"/>
    </xsl:template>

    <xsl:template match="myel">
        <xsl:for-each select="@*">
            <xsl:value-of select="."/>
            <xsl:value-of select="','"/>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:template> 
</xsl:stylesheet>

XMLSTARLET è un toolkit della riga di comando per query/modifica/controlla/trasforma i documenti XML (per ulteriori informazioni, consultare http://xmlstar.sourceforge.net/)

Nessun file da scrivere, basta reindirizzare il file a xmlstarlet e applicare un filtro xpath.

cat file.xml | xml sel -t -m 'xpathExpression' -v 'elemName' 'literal' -v 'elname' -n

-m espressione -v valore '' incluso letterale -n newline

Quindi per la tua XPath l'espressione XPath sarebbe // Myel/@Nome che fornirebbe i due valori degli attributi.

Strumento molto utile.

Ecco un piccolo script Ruby che lo fa esattamente cosa chiede la tua domanda (estrai un attributo chiamato "nome" dagli elementi chiamati "myel").Dovrebbe essere facile generalizzare

#!/usr/bin/ruby -w

require 'rexml/document'

xml = REXML::Document.new(File.open(ARGV[0].to_s))
xml.elements.each("//myel") { |el| puts "#{el.attributes['name']}," if el.attributes['name'] }

Rispondendo alla domanda originale, presupponendo che il file xml sia "test.xml" che contiene:

<root> <myel name="Foo" /> <myel name="Bar" /> </root>

cat text.xml | tr -s "\"" " " | awk '{printf "%s,\n", $3}'

il tuo file di test è in test.xml.

sed -n 's/^\s`*`&lt;myel\s`*`name="\([^"]`*`\)".`*`$/\1,/p' test.xml

Ha le sue insidie, ad esempio se non è rigorosamente dato che ciascuna mioel è su una riga che devi prima "normalizzare" il file xml (quindi ciascuno mioel è su una riga separata)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top