0

I would like to search across multiple XML files for nodes with an optional attribute. The files missing the attribute I am looking for do not declare the namespace it belongs. I am searching using a simple XPath as in the following example:

Here I am interested in the other_attribute of node:

<?xml version="1.0" encoding="UTF-8"?>
<otherfile xmlns:xs="something" xmlns:optional="something_else">
  <node attribute = "hohoho" optional:other_attribute= "mary Xmass">
  </node>
</otherfile>

And I am matching it using the XPath //@optional:other_attribute. However, when trying to do the same in the following file:

<?xml version="1.0" encoding="UTF-8"?>
<file xmlns:xs="something">
    <node attribute = "hohoho">
    </node>
</file>

The search fails because the namespace optional is not declared in the second example file. Is there a way to do a conditional search for the attribute with using the Xpath syntax?

2
  • Do you want to fetch node either with @optional:other_attribute or with @other_attribute? Or you want to fetch node with either @optional:other_attribute or @attribute? Can you clarify? It's not clear from description. Commented Nov 24, 2020 at 11:46
  • Sorry didn't explain it very well, what I would like to do is to fetch @optional:other_attribute only if it exists. My problem is that the Xpath query fails if the namespace is not declared instead of just returning nothing (node does not exist) Commented Nov 24, 2020 at 12:01

2 Answers 2

1

This should work

//@*[name()="optional:other_attribute"]
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @DonnyFlaw, however I tried //@*[local-name()=("other_attribute")] and it seems to work most of the time. If I understand correctly it will match any attribute named other_attribute regardless of namespace. So when I have attributes from other namespaces with the same name it also matches them. Is there a way to avoid doing so?
@DiamantisSellis try this one //@*[name()="optional:other_attribute"]
0

If I understand you correctly, the easiest way to do this is to switch the expression to local-name(). With the expression

//*[@*/local-name()="other_attribute"]

would select the correct node in the first example and select no nodes in the other.

1 Comment

It should be noted that this XPath is only valid in XPath 2.0 or higher.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.