Pregunta

A veces necesito extraer rápidamente algunos datos arbitrarios de archivos XML para ponerlos en formato CSV.¿Cuáles son sus mejores prácticas para hacer esto en la terminal Unix?Me encantaría recibir algunos ejemplos de código, así que, por ejemplo, ¿cómo puedo resolver el siguiente problema?

Ejemplo de entrada XML:

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

Mi salida CSV deseada:

Foo,
Bar,
¿Fue útil?

Solución

Si solo desea los atributos de nombre de cualquier elemento, aquí tiene una solución rápida pero incompleta.

(Su texto de ejemplo está en el archivo ejemplo)

Ejemplo de "nombre" de GREP | cortar -d "" "-f2,2 | xargs -i {} echo" {}, ","

Otros consejos

la respuesta de pedro es correcto, pero genera un avance de línea final.

<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>

Simplemente ejecute, por ej.

xsltproc stylesheet.xsl source.xml

para generar los resultados CSV en la salida estándar.

Utilice un procesador XSLT de línea de comandos como xsltproc, sajón o xalán para analizar el XML y generar CSV.Aquí está un ejemplo, que para tu caso es la hoja de estilo:

<?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 es un kit de herramientas de línea de comando para consultar/editar/verificar/transformar documentos XML (para obtener más información consulte http://xmlstar.sourceforge.net/)

No hay archivos que escribir, simplemente canalice su archivo a xmlstarlet y aplique un filtro xpath.

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

-m expresión -v valor '' incluyó literal -n newline

Entonces, para su XPath, la expresión de XPath sería // name/@name que proporcionaría los dos valores de atributos.

Herramienta muy útil.

Aquí hay un pequeño script Ruby que hace exactamente lo que plantea su pregunta (extraiga un atributo llamado 'nombre' de los elementos llamados 'myel').Debería ser fácil de generalizar

#!/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'] }

Respondiendo a la pregunta original, asumiendo que el archivo xml es "test.xml" que contiene:

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

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

su archivo de prueba está en test.xml.

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

Tiene sus inconvenientes, por ejemplo si no se tiene en cuenta estrictamente que cada miel está en una línea, primero debe "normalizar" el archivo xml (de modo que cada miel está en una línea separada)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top