evaluateXPathExpression attributes of element with namespace

Contributor ,
Mar 24, 2022 Mar 24, 2022

Copy link to clipboard

Copied

I have an xml like this (reduced example):

<root xmlns:test="http://ns.test.com/test/2.0">
    <test:master>
        <test:graphic control="ABC"/>
        <test:textframe>TEXT</test:textframe> 
    </test:master>

    <test:master>
        <test:graphic control="XYZ"/>
        <test:textframe>TEXT</test:textframe> 
    </test:master>
</root>

As you can see the "test:graphic" element contains a "control" attribute.

I'd like to get all elements with a "control" attribute of the first "master" element with evaluateXPathExpression.

 

WITHOUT namespaces this code works:

var root = doc.xmlElements[0]; // doc is the current document
var xmlElements = root.xmlElements[0].evaluateXPathExpression("//*[@control]");
--> 1 result

 

But WITH namespaces it doesn't:

var namespaces = new Array(new Array("test","http://ns.test.com/test/2.0"));
var root = doc.xmlElements[0]; // doc is the current document
var xmlElements = root.xmlElements[0].evaluateXPathExpression("//*[@control]",namespaces);
--> 0 results

 

Althoug it works WITH namespaces on the root element (not on the first "master" like above) 

var namespaces = new Array(new Array("test","http://ns.test.com/test/2.0"));
var root = doc.xmlElements[0]; // doc is the current document
var xmlElements = root.evaluateXPathExpression("//*[@control]",namespaces); //
--> 2 results

 

So i was wondering what am i doing wrong and how adress only a specific "master" element.

TOPICS
Scripting

Views

93

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Contributor , Mar 25, 2022 Mar 25, 2022
I think i found a solution: root.evaluateXPathExpression("//test:master[1]/*[@control]",namespaces);

Likes

Translate

Translate
Guide ,
Mar 25, 2022 Mar 25, 2022

Copy link to clipboard

Copied

Try "//*[@*[local-name()='control']]"

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 25, 2022 Mar 25, 2022

Copy link to clipboard

Copied

Hi Dirk

 

Thank you for your help!

It works if i adress the root

 

 

var namespaces = new Array(new Array("test","http://ns.test.com/test/2.0"));
var root = doc.xmlElements[0]; // doc is the current document
var xmlElements = root.evaluateXPathExpression("//*[@*[local-name()='control']]",namespaces); //
--> 2 results

 

 

 

But it doesn't if i adress a child of root (what i'm looking for)

 

 

var namespaces = new Array(new Array("test","http://ns.test.com/test/2.0"));
var root = doc.xmlElements[0]; // doc is the current document
var xmlElements = root.xmlELements[0].evaluateXPathExpression("//*[@*[local-name()='control']]",namespaces); //
--> 0 results

 

 

  

Maybe there's another approach? Is there a possibility to adress the n'th element of root like so:

 

 

root.evaluateXPathExpression("//test:master[n]/*[@control]",namespaces)

 

 

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Mar 25, 2022 Mar 25, 2022

Copy link to clipboard

Copied

I think i found a solution:

 

root.evaluateXPathExpression("//test:master[1]/*[@control]",namespaces);

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Mar 25, 2022 Mar 25, 2022

Copy link to clipboard

Copied

LATEST

Good that you found that yourself, before re-reading your original post I had assumed your actual trouble was with the missing namespace on the attribute name, rather than addressing the first test:master element. Apparently with your apporach the attribute now works even without that complex expression.

 

Note that the double slash asks to search the test:master at any depth, it should be possible to just use a single slash - or would it be "/root/test:master ..."? This may become performance relevant with larger structures. There should also be an advantage when you start off from your root.xmlElements[0], of course if you get it to work at all.

 

I currently wonder why you need that extra namespaces argument, given there is already the xmlns:test at the root. On the other hand I haven't used namespaces for in-document XML (strip them out with an XSLT during import) and when I use xpath at all I use xmlRules for historical reasons (some bugs fixed back in CS5).

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines