xmlstarlet默认命名空间

时间:2018-07-12 15:47:38

标签: xml xslt namespaces xmlstarlet

我想使用xmlstarlet将第三方xml文件转换为csv文件。在最精确的解释中,有些文件使用带有xmlns声明的默认名称空间,另一些使用不带有xmlns声明的默认名称空间,而其他文件在严格的解释中使用严格的默认名称空间。

这是较小的文件,应该可以澄清我的问题。
foo1.xml

<?xml version="1.0"?>
<root xmlns="http://my.namespace" xmlns:fooNS="http://foo.namespace" xmlns:barNS="http://bar.namespace">
    <fooNS:foo id="1">FOO 1</fooNS:foo>
    <fooNS:foo id="2">FOO 2</fooNS:foo>
    <barNS:bar ref="2" unitRef="Unit1">2000</barNS:bar>
    <unit id="Unit1">
        <measure>bars</measure>
    </unit>
</root>

foo2.xml

<?xml version="1.0"?>
<root xmlns:fooNS="http://foo.namesapece" xmlns:barNS="http://bar.namespace">
    <fooNS:foo id="1">FOO 1</fooNS:foo>
    <fooNS:foo id="2">FOO 2</fooNS:foo>
    <barNS:bar ref="2" unitRef="Unit1">2000</barNS:bar>
    <unit id="Unit1">
        <measure>bars</measure>
    </unit>
</root>

foo3.xml

<?xml version="1.0"?>
<myNS:root xmlns:myNS="http://my.namespace" xmlns:fooNS="http://foo.namesapece" xmlns:barNS="http://bar.namespace">
    <fooNS:foo id="1">FOO 1</fooNS:foo>
    <fooNS:foo id="2">FOO 2</fooNS:foo>
    <barNS:bar ref="2" unitRef="Unit1">2000</barNS:bar>
    <unit id="Unit1">
        <measure>bars</measure>
    </unit>
</myNS:root>

现在,我想要一个带有"FOO 2 | 2000 | bars"的文件作为输出。属性“ unitRef”在xsd中定义为IDREF。

此命令适用于 foo1.xml (但不适用于foo2.xml和foo3.xml):

$> xmlstarlet sel -N xbrli="http://my.namespace" \
         -t -m "//fooNS:foo[../barNS:bar/@ref = @id]"
         -v . -o " | " \
         -v "../barNS:bar[@ref=current()/@id]" -o " | " \
         -v \
"//xbrli:unit[@id=current()/../barNS:bar[@ref=current()/@id]/@unitRef]/xbrli:measure" \
         -n foo1.xml

此命令适用于 foo2.xml和foo3.xml (但不适用于foo1.xml):

$> xmlstarlet sel -N xmlns="http://my.namespace" \
         -t -m "//fooNS:foo[../barNS:bar/@ref = @id]" \
         -v . -o " | " \
         -v "../barNS:bar[@ref=current()/@id]" -o " | " \
         -v \
"//unit[@id=current()/../barNS:bar[@ref=current()/@id]/@unitRef]/measure" \
         -n foo[23].xml

问题:是否有适用于所有三个第三方文件的语法?如果不使用xmlstarlet,那么也许使用xslt文件?还是有可能处理所有xml文件(使用xmlstarlet或xslt),以便它们表现相似?

谢谢。

1 个答案:

答案 0 :(得分:0)

因为没有人提供更好的解决方案,所以我使用了#kjhughes提出的解决方案。

所以(不推荐)答案: -v“ // [本地名称()='单位'] [@ id = current()/../ barNS:bar [@ ref = current()/ @ id] / @ unitRef] / < / em> [local-name()='measure']“

有关所有推荐解决方案的说明,另请参见“ How does XPath deal with XML namespaces?”。但是它们都不适合我所有的情况。