Home > database >  Namespace resolver supporting default namespace in xml to evaluate xpath
Namespace resolver supporting default namespace in xml to evaluate xpath

Time:01-11

My XML document starts like :

<?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>

I need to find elements with xpath queries like :

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

Because of default namespace xmlns="http://docbook.org/ns/docbook" associated to another explicit namespace, the namespace resolver fails when evaluating xpath expressions.

As I understand the note in https://developer.mozilla.org/en-US/docs/Web/XPath/Introduction_to_using_XPath_in_JavaScript#implementing_a_default_namespace_resolver , there is no simple pattern to support "normal xpath expression" with such a declaration of namespaces. Proposed solution using "namespace-uri()=[...]" seems to complexify xpath expressions.

Anyone has a pattern to propose ?

CodePudding user response:

Use XPath 3.1 with 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>

  •  Tags:  
  • Related