Анализ XML с использованием терминала unix

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

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

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

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

Foo,
Bar,

Ответ 1

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

(Пример вашего примера приведен в примере файла)

grep "name" example | cut -d "\" "-f2,2 | xargs -I {} echo" {},"

Ответ 2

Ответ Питера правильный, но он выводит кортеж задней линии.

<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 в стандартный вывод.

Ответ 3

Использовать XSLT-процессор командной строки, например xsltproc, saxon или xalan для анализа 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>

Ответ 4

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 newline

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

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

НТН

Ответ 5

Здесь немного ruby ​​ script, который точно выполняет ваш вопрос (вытащите атрибут под названием "имя" из элементов, называемых "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'] }

Ответ 6

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

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

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

Ответ 7

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

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

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