Правильный способ извлечь содержимое из XML является с реальным, живым XML парсер. XMLStarlet является onesuch.
Обратите внимание, что это требует данных, чтобы быть фактической XML, что существующие данные не без корневого элемента добавляется.
xmlstarlet sel -t -m '//element' -v ./@attr1 -o '(' -v ./@attr3 -o ')' -n <<EOF
<root>
<element attr1="val11" attr2="val12" attr3="val13" />
<element attr1="val21" attr2="val22" attr3="val23" />
<element attr1="val31" attr2="val32" attr3="val33" />
</root>
EOF
Чтобы объяснить, как это работает:
-t
начинается новый шаблон
-m //element
соответствует элементу с именем element
в любом месте документа.
-v ./@attr1
излучает содержание атрибута с именем attr1
-o '('
излучает буквальный (
в виде строки
-v ./@attr3
излучает содержание атрибута с именем attr3
-o ')'
излучает буквальный )
в виде строки
-n
испускает литерал новой строки
Если вы хотите иметь возможность запускать это на компьютерах, на которых не установлен XMLStarlet, вы можете создать шаблон XSLT и вызвать его с помощью XSLTProc, который широко доступен.
Запуск xmlstarlet sel -C -t -m '//element' -v ./@attr1 -o '(' -v ./@attr3 -o ')' -n
выдает следующий XSLT-файл:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0" extension-element-prefixes="exslt">
<xsl:output omit-xml-declaration="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="//element">
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="./@attr1"/>
</xsl:call-template>
<xsl:text>(</xsl:text>
<xsl:call-template name="value-of-template">
<xsl:with-param name="select" select="./@attr3"/>
</xsl:call-template>
<xsl:text>)</xsl:text>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="value-of-template">
<xsl:param name="select"/>
<xsl:value-of select="$select"/>
<xsl:for-each select="exslt:node-set($select)[position()>1]">
<xsl:value-of select="' '"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Если вы сохраните это как myproc.xslt
и запустить xsltproc myproc.xslt - <input.xml
, вы получите желаемый результат на стандартный вывод.
Этот XML кажется недопустимым. – yanana