题
有时我需要快速从 XML 文件中提取一些任意数据以放入 CSV 格式。在 Unix 终端中执行此操作的最佳实践是什么?我想要一些代码示例,那么例如我怎样才能解决以下问题?
XML 输入示例:
<root>
<myel name="Foo" />
<myel name="Bar" />
</root>
我想要的 CSV 输出:
Foo,
Bar,
解决方案
如果您只想要任何元素的名称属性,这里有一个快速但不完整的解决方案。
(您的示例文本位于文件中 例子)
grep“名称”示例|切割-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>
</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
只需运行例如
xsltproc stylesheet.xsl source.xml
将 CSV 结果生成为标准输出。
使用命令行 XSLT 处理器,例如 xslt过程, 撒克逊人 或者 夏兰 解析 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> </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 newline
因此,对于您的xpath xpath表达式将为// myel/@名称,它将提供两个属性值。
非常方便的工具。
这是一个小 ruby 脚本 确切地 你的问题问什么(从名为“myel”的元素中提取一个名为“name”的属性)。应该很容易概括
#!/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`*`<myel\s`*`name="\([^"]`*`\)".`*`$/\1,/p' test.xml
它有它的陷阱,例如,如果没有严格考虑每个 迈耶尔 在一行上,您必须首先“规范化”xml 文件(因此每个 迈耶尔 位于单独的一行上)