这是一个愚蠢的XPATH问题。代码是PL / SQL,但它无关紧要。
lx_a := XMLTYPE('<rfs-graph><graphml>foo</graphml><rfs-graph>');
lx_b := lx_a.extract('/rfs-graph/graphml[1]');
dbms_output.put_line(lx_b.getStringVal());
运行时,结果为
<graphml>foo</graphml>
但是当运行此代码时:
lx_a := XMLTYPE('<rfs-graph><graphml xmlns="abc">foo</graphml></rfs-graph>');
lx_b := lx_a.extract('/rfs-graph/graphml[1]');
dbms_output.put_line(lx_b.getStringVal());
失败,因为lx_b为空。
唯一的区别是graphml元素有一个属性。
如何选择graphml元素,无论它是否具有属性?
答案 0 :(得分:2)
实际上它没有属性而是xml名称空间声明。所以你的xpath正在寻找null命名空间中的graphml元素,但是只有来自“abc”命名空间的graphml元素。因此它找不到任何东西。
您可以使用例如跟随xpath
/rfs-graph/node()[local-name() = 'graphml' and namespace-uri() = 'abc']
答案 1 :(得分:2)
xmlns="abc"
不是标准属性,而是namespace prefix declaration。在这种情况下,因为省略了前缀,实际上是为该节点(以及所有子节点)指定了默认命名空间
您的XPath在第二种情况下不匹配的原因是因为节点的名称不仅仅是graphml
,而是abc:graphml
,即它在abc
namesapce中。你的XPath看起来应该是这样的。
/rfs-graph/a:graphml[1]
如果前缀a
已映射到abc
命名空间,我认为在PL / SQL中执行此操作的方式如下
lx_b := lx_a.extract('/rfs-graph/a:graphml[1]', 'xmlns:a="abc"');
但我不确定,因为我之前从未写过一行PL / SQL。