skip to Main Content

I am attempting to use the Javascript Document evaluate function with valid XPath that uses the name() / local-name() function but am consistently getting the following error in Jfiddle:

The string '/foods/*[position()=1</a>/local-name()' is not a valid XPath expression

It is unclear how or why the </a> fragment is introduced

Sample code is as follows:

const xml = "<foods><meat>chicken</meat><fruit>orange</fruit><fruit>apple</fruit><fruit>banana</fruit></foods>";

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

for ( var i = 0 ; i < 4; i++ ){
const xpath = `/foods/*[position()=${i+1}]`;
const xpathValue = document.evaluate(
  xpath,
  doc,
  null,
  XPathResult.STRING_TYPE,
  null
);
const xpathName = document.evaluate(
  `${xpath}/local-name()`,
  doc,
  null,
  XPathResult.STRING_TYPE,
  null
);

console.log(`${xpathName.stringValue} = ${xpathValue.stringValue}`);
}

The XPath evalutaing the value works fine, just not the node name. Any assistance would be appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks @Martin Honnen - working code

    onst xml = "<foods><meat>chicken</meat><fruit>orange</fruit><fruit>apple</fruit><fruit>banana</fruit></foods>";
    
    const doc = new DOMParser().parseFromString(xml,'application/xml');
    
    for ( var i = 0 ; i < 4; i++ ){
    const xpath = `/foods/*[position()=${i+1}]`;
    const xpathValue = doc.evaluate(
      xpath,
      doc,
      null,
      XPathResult.STRING_TYPE,
      null
    );
    let resolver = function () { return "http://www.w3.org/2005/xpath-functions";}
    const xpath2 = `name(/foods/*[position()=${i+1}])`;
    console.log(xpath2);
    const xpathName = doc.evaluate(
      xpath2,
      doc,
      resolver,
      XPathResult.STRING_TYPE,
      null
    );
    
    console.log(`${xpathName.stringValue} = ${xpathValue.stringValue}`);
    }
    
    

  2. You can use XPath 3.1 with SaxonJS 2:

    const xml = "<foods><meat>chicken</meat><fruit>orange</fruit><fruit>apple</fruit><fruit>banana</fruit></foods>";
    
    const doc = new DOMParser().parseFromString(xml,'application/xml');
    
    const result = SaxonJS.XPath.evaluate(`/foods/*/(name() || ' = ' || string())`, doc);
    
    console.log(result);
    <script src="https://martin-honnen.github.io/SaxonJS-2.6/SaxonJS2.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search