命名空间解析器支持 xml 中的默认命名空间来评估 xpath

Namespace resolver supporting default namespace in xml to evaluate xpath

提问人:Florimond 提问时间:1/10/2022 更新时间:1/10/2022 访问量:263

问:

我的XML文档是这样开始的:

<?xml version='1.0' encoding='UTF-8'?>
<article  xmlns:d="http://docbook.org/ns/docbook"
          xmlns="http://docbook.org/ns/docbook"
          version="5.0">
<info>
 <title>My title</title>
 <annotation>
   <segmentedlist>
     <segtitle>role</segtitle>
     <segtitle>id</segtitle>
     <segtitle>description</segtitle>
     <seglistitem>
       <seg>input</seg>
       <seg>hash123</seg>
       <seg>INPUT</seg>
     </seglistitem>
   </segmentedlist>
  </annotation>
 </info>
 <simpara/>
</article>

我需要使用 xpath 查询查找元素,例如:

var inputList = currentDocument.evaluate("//annotation/segmentedlist/seglistitem/seg",
                                          currentDocument,
                                          null,
                                          XPathResult.ANY_TYPE,null);

由于默认命名空间 xmlns=“http://docbook.org/ns/docbook” 与另一个显式命名空间相关联,因此命名空间解析程序在计算 xpath 表达式时失败。

据我了解,https://developer.mozilla.org/en-US/docs/Web/XPath/Introduction_to_using_XPath_in_JavaScript#implementing_a_default_namespace_resolver 中的注释,没有简单的模式来支持具有这种命名空间声明的“普通 xpath 表达式”。 使用“namespace-uri()=[...]”提出的解决方案似乎使 xpath 表达式复杂化。

有人有要提议的模式吗?

JavaScript XML XPath 命名空间

评论


答:

1赞 Martin Honnen 1/10/2022 #1

将 XPath 3.1 与 Saxon-JS 2 (https://www.saxonica.com/saxon-js/documentation2/index.html) 一起使用:

const xml = `<?xml version='1.0' encoding='UTF-8'?>
<article  xmlns:d="http://docbook.org/ns/docbook"
          xmlns="http://docbook.org/ns/docbook"
          version="5.0">
<info>
 <title>My title</title>
 <annotation>
   <segmentedlist>
     <segtitle>role</segtitle>
     <segtitle>id</segtitle>
     <segtitle>description</segtitle>
     <seglistitem>
       <seg>input</seg>
       <seg>hash123</seg>
       <seg>INPUT</seg>
     </seglistitem>
   </segmentedlist>
  </annotation>
 </info>
 <simpara/>
</article>`;

const xmlDoc = new DOMParser().parseFromString(xml, 'application/xml');

const segElements = SaxonJS.XPath.evaluate('//annotation/segmentedlist/seglistitem/seg', xmlDoc , { 'xpathDefaultNamespace' : 'http://docbook.org/ns/docbook' });

console.log(segElements.length, segElements);
<script src="https://www.saxonica.com/saxon-js/documentation2/SaxonJS/SaxonJS2.rt.js"></script>