Pergunta

Às vezes eu preciso rapidamente extrair alguns dados arbitrários a partir de arquivos XML para colocar em um formato CSV.O que há de seus melhores práticas para fazer isso no terminal Unix?Eu gostaria de alguns exemplos de código, então, por exemplo, como posso obter o seguinte problema resolvido?

Exemplo de XML de entrada:

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

Meu desejada de saída CSV:

Foo,
Bar,
Foi útil?

Solução

Se você quiser apenas o nome de atributos de qualquer elemento, aqui é um rápido, mas solução incompleta.

(Seu texto de exemplo está no arquivo exemplo)

grep "nome" exemplo | cut-d"\"" -f2,2 | xargs -I{} echo "{},"

Outras dicas

Pedro resposta está correto, mas as saídas de um ponto à direita da linha de alimentação.

<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 executar e.g.

xsltproc stylesheet.xsl source.xml

para gerar o CSV resultados na saída padrão.

Utilizar uma linha de comandos processador XSLT como o xsltproc, saxon ou xalan para analisar o XML e gerar CSV.Aqui um exemplo, que para o seu caso é a folha de estilos:

<?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 é um kit de ferramentas de linha de comando para consultar/editar/check/transformação Documentos XML (para obter mais informações, consulte http://xmlstar.sourceforge.net/)

Não há arquivos para escrever, apenas pipe seu arquivo para xmlstarlet e aplicar um filtro xpath.

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

-m de expressão v valor "incluídos literal -n nova linha

Então, para xpath xpath expressão seria //myel/@nome o que daria os dois valores de atributo.

Ferramenta muito útil.

Aqui está um pouco do script ruby que faz exatamente o que a sua pergunta pede (puxar um atributo chamado "nome" de elementos chamados 'myel').Deve ser fácil para 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'] }

Respondendo a pergunta original, supondo que o arquivo xml é "test.xml" que contém:

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

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

seu arquivo de teste em test.xml.

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

Ele tem suas armadilhas, por exemplo, se não é estritamente dado que cada myel é uma linha que você tem para "normalizar" o arquivo xml primeiro (para cada myel é em uma linha separada)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top