Синтаксический анализ XML с помощью терминала unix

StackOverflow https://stackoverflow.com/questions/29004

Вопрос

Иногда мне нужно быстро извлечь некоторые произвольные данные из XML-файлов, чтобы перевести их в формат CSV.Каковы ваши наилучшие методы для выполнения этого в терминале Unix?Мне бы хотелось привести несколько примеров кода, например, как я могу решить следующую проблему?

Пример ввода XML:

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

Мой желаемый результат в формате CSV:

Foo,
Bar,
Это было полезно?

Решение

Если вам просто нужны атрибуты name любого элемента, вот быстрое, но неполное решение.

(Ваш пример текста находится в файле пример)

пример grep "name" | вырезать -d"\"" -f2,2 | xargs -I{} echo "{},"

Другие советы

Ответ Питера является правильным, но он выводит перевод строки в конце.

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

Просто запустите, например

xsltproc stylesheet.xsl source.xml

сгенерировать результаты CSV в стандартный вывод.

Используйте XSLT-процессор командной строки, такой как xsltproc, саксонец или ксалан чтобы проанализировать XML и сгенерировать CSV.Вот пример, что в вашем случае является таблицей стилей:

<?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 - это набор инструментов командной строки для запроса / редактирования / проверки / преобразования XML-документов (для получения дополнительной информации см. http://xmlstar.sourceforge.net/)

Никаких файлов для записи, просто передайте ваш файл в xmlstarlet и примените фильтр xpath.

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

-m выражение -v значение " включенный литерал -n перевод строки

Таким образом, для вашего xpath выражением xpath было бы //myel/@name , которое предоставляло бы два значения атрибута.

Очень удобный инструмент.

Вот небольшой ruby-скрипт, который делает именно так что задается в вашем вопросе (извлеките атрибут с именем 'name' из элементов с именем 'myel').Должно быть легко обобщить

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

Отвечая на исходный вопрос, предполагая, что XML-файл "test.xml" содержит:

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

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

ваш тестовый файл находится в test.xml.

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

В этом есть свои подводные камни, например, если строго не указано, что каждый миэль находится в одной строке, вы должны сначала "нормализовать" xml-файл (так что каждый миэль находится на одной отдельной строке)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top