2008-08-26 4 views
11

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

Пример входных данных XML:

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

Моя требуемый выход CSV:

Foo, 
Bar, 

ответ

5

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

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

Grep например "имя" | вырезать -d "\"»-f2,2 | xargs -I {} эхо "{}"

9

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

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

Peter's answer является правильным, но он выводит канал задней линии

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

Just. запустить например

xsltproc stylesheet.xsl source.xml 

для получения результатов, CSV в стандартный вывод.

1

Вот маленький рубиновый скрипт, который делает точно что ваш вопрос спрашивает (вытащите атрибут под названием «имя» из элементов, называемых «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

XMLStarlet является командной строки инструментария для запроса/редактирования/проверки/преобразования XML документов (для получения дополнительной информации не вижу http://xmlstar.sourceforge.net/)

Нет файлов писать, только трубы ваш файл xmlstarlet и применить фильтр xpath.

cat file.xml | XML Сель -t -m 'XPathExpression' -v 'elemName' 'дословный' -v 'elname' -n -m выражение -v значение '' включены буквальным -n новой строки

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

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

НТН

+0

XMLStarlet, похоже, не обновляется совсем недавно – Vihung 2012-10-02 14:21:16

0

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

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

Он имеет это подводные камни, например, если он не является строго учитывая, что каждый myel находится на одной линии, вы должны «нормализовать» файл XML первый (так что каждый myel находится на одной отдельной строке)

1

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

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

cat text.xml | tr -s "\"" " " | awk '{printf "%s,\n", $3}' 
Смежные вопросы