Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to get attribute value without namespace?

Tags:

xml

xpath

I am using xpath to extract the value of an attribute but the attribute has a namespace, how can I get the value of the xpath without the namespace or better yet, is there a way to replace the namespace with another?

xpath looks something like this

string(//*:root/*:element/@attribute)

this returns _01_1:SomeValue I want just SomeValue or ns:SomeValue.

Unfortunately, I cannot share the actual XML but the below is a xml that can be used for reference.

<root xmlns:_01_1="http://SOMEURL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<element xsi:attribute="_01_1:SomeValue">Element Value</element>
</root>

Here i want to have just SomeValue or maybe replace _01_1 with something (like ns) and get ns:SomeValue

like image 839
Abhishek Asthana Avatar asked Aug 17 '26 21:08

Abhishek Asthana


1 Answers

Have you tried using local-name()?

string(root/*:element/@*[local-name()='attribute']) This will give you "SomeValue" instead of "_01_1:SomeValue".

Example:

<root>
<hello xmlns:foo="http:asdf.com">
<something foo:yo="hi">
</something>
</hello>
</root>

string(root/hello/@*[local-name()='yo']) 

returns 'hi'

If you have something like:

<root>
    <hello xmlns:foo="http:asdf.com">
    <something foo:yo="01_1:hi">
    </something>
    </hello>
    </root>

And want the 01_1: removed, you could wrap the result in translate like so:

translate(string(root/hello/@*[local-name()='yo']),"_01_1:","")

You could apply the above to your original XPath without the use of local-name() if you wish to go this route.

For the supplied XML in the question:

translate(string(root/element/@*[local-name()='attribute']), "_01_1:","")

@* will return all attributes of the node, so in this case all attributes of element. You can replace anything you wish with the translate() operation as I did with a blank space, and it will map the given parameter of "_01_1:" to that value. So if you would prefer a result of "ns:SomeValue" then use:

translate(string(root/element/@*[local-name()='attribute']), "_01_1:","ns:")

Using // in place of just root is an example of a relative path vs an absolute path. If you are unsure of where in the document you are looking for your data or where your target node begins, you can use the // and * identifiers to check a broader range. Ex) //root = "Start at the root element and follow all paths starting from the top and traversing to the bottom" while just root/element/etc will say "only check the etc nodes following a direct path from root->element->etc, and is relative to the literal root of the document.

like image 95
JWiley Avatar answered Aug 22 '26 04:08

JWiley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!