使用UNIX脚本/命令
这里提取从XML文件中的值到字段分隔符格式示例文件,我们需要值转换为分隔符格式的文件: -使用UNIX脚本/命令
的test.xml
<?xml version="1.0" encoding="UTF-8" ?>
<testjar>
<testable>
<trigger>Trigger1</trigger>
<message>2012-06-14T00:03.54</message>
<sales-info>
<san-a>no</san-a>
<san-b>no</san-b>
<san-c>no</san-c>
</sales-info>
</testable>
<testable>
<trigger>Trigger2</trigger>
<message>2012-06-15T00:03.54</message>
<sales-info>
<san-a>yes</san-a>
<san-b>yes</san-b>
<san-c>no</san-c>
</sales-info>
</testable>
</testjar>
每个记录应该从新线开始。样本结果集应该是这样的 sample.txt的
Trigger1|2012-06-14T00:03.54|no|no|no
Trigger2|2012-06-15T00:03.54|yes|yes|no
注: - xmlstarlet是不是我的服务器上安装,是不是可以不xmlstarlet执行此?
如果您已经安装xmlstarlet,你可以尝试:命令
[email protected]$ xmlstarlet sel -t -m "//testable" -v trigger -o "|" -v message -o "|" -m sales-info -v san-a -o "|" -v san-b -o "|" -v san-c -n test.xml
Trigger1|2012-06-14T00:03.54|no|no|no
Trigger2|2012-06-15T00:03.54|yes|yes|no
击穿:
xmlstarlet sel -t
-m "//testable" # match <testable>
-v trigger -o "|" # print out value of <trigger> followed by |
-v message -o "|" # print out value of <message> followed by |
-m sales-info # match <sales-info>
-v san-a -o "|" # print out value of <san-a> followed by |
-v san-b -o "|" # print out value of <san-b> followed by |
-v san-c # print out value of <san-c>
-n # print new line
test.xml # INPUT XML FILE
来定位内<testable>
不同的标签,你可以尝试返回文本以下所有叶节点:
[email protected]$ xmlstarlet sel -t -m "//testable" -m "descendant::*[not(*)]" -v 'text()' -i 'not(position()=last())' -o '|' -b -b -n test.xml
Trigger1|2012-06-14T00:03.54|no|no|no
Trigger2|2012-06-15T00:03.54|yes|yes|no
c ommand:
xmlstarlet sel -t
-m "//testable" # match <testable>
-m "descendant::*[not(*)]" # match all leaf nodes
-v 'text()' # print text
-i 'not(position()=last())' -o '|' # print | if not last item
-b -b # break out of nested matches
-n # print new line
test.xml # INPUT XML FILE
如果您没有访问xmlstarlet
,那么就查找您在您的处置有什么其他的工具。其他选项包括xsltproc(请参阅mzjn's answer)和xpath。
如果这些工具不可用,我会建议使用更高级别的语言(Python,Perl),它允许您访问正确的XML库。
虽然可以使用手动regex
解析它,这样的解决方案将是不理想†特别是不一致的输入。例如,下面的(假设你有gawk
和sed
)把你的输入,并应吐出预期输出:
[email protected]$ gawk 'match($0, />(.*)</, a){printf("%s|",a[1])} /<\/testable>/{print ""}' test.xml | sed 's/.$//'
Trigger1|2012-06-14T00:03.54|no|no|no
Trigger2|2012-06-15T00:03.54|yes|yes|no
然而,这遭到惨败,如果输入格式的变化,因此不是一个解决方案,我一般会推荐。
在这里捕捉是我的文件(xml页面会增加或减少)会不断变化..有一个命令可以处理这个问题吗? – 2012-07-26 09:04:23
你的意思是'
是的..但是我们可以在另一个文件中存储tages,并在这里获取信息...我们可以管理这个..很大的问题是不幸的是我没有xmlstarlet在我的服务器上:-(这可能没有xmlstarlet? – 2012-07-26 09:18:08
这里是一个XSLT样式表,你想要做什么(保存在test.xsl):
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="testable">
<xsl:value-of select='trigger'/><xsl:text>|</xsl:text>
<xsl:value-of select='message'/><xsl:text>|</xsl:text>
<xsl:value-of select='sales-info/san-a'/><xsl:text>|</xsl:text>
<xsl:value-of select='sales-info/san-b'/><xsl:text>|</xsl:text>
<xsl:value-of select='sales-info/san-c'/><xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
命令(在这里我假设你已经安装了libxml2和的libxslt; xsltproc是一个命令行工具,使用这些库):
xsltproc -o sample.txt test.xsl test.xml
样品的内容。TXT:
Trigger1|2012-06-14T00:03.54|no|no|no
Trigger2|2012-06-15T00:03.54|yes|yes|no
x mlstarlet没有安装在我的服务器..是否有可能没有xmlstarlet? – 2012-07-26 09:18:52
是的,这是可能的。 – mzjn 2012-07-26 10:04:17
这里是一个纯bash的解决方案:
egrep '<trigger>|<message>|<san-.>' test.xml | sed -e 's/<[^>]*>//g' | while read line; do [ $((++i % 5)) -ne 0 ] && echo -n "$line|" || echo $line ; done
但是,它只能在格式化为您的样品(在一个单独的行中的每个元素)在文件中,它甚至没有密切灵活/可靠的其他答案涉及正确的XML解析/转换。
它可以增强,虽然在一定程度上...
不错,谢谢 – 2014-03-21 05:42:32
请修正''? –
kev
2012-07-26 08:36:37