3

How to extract the value of /substance/text and /makers/text?

I am expecting the result to be

  1. Automation
  2. Test Record

I have tried many things for example:

  • //*[local-name()='text/@value']
  • //*[local-name()='substance']/text/text()
  • //*[local-name()='name'][1]
    (This works for first name element but if I use similar for text it doesn't work.)
  • //*[local-name()='text/@value'][1]
  • //*[local-name()='text'][1]
<health xmlns="http://test.com/sample">
    <substance>
        <name>substance</name>
        <text value="Automation"/>
    </substance>
    <user>
        <reference value="User/111111122"/>
    </user>
    <reaction>
        <makers>
            <name>makers</name>
            <text value="Test Record"/>
        </makers>
    </reaction>
</health>
1
  • The examples of what you tried show that you're guessing, and you're not really understanding what any of these expressions mean. You need to do some reading to get a better grasp of the concepts! Clearly there's no element in your document whose name is 'text/@value' - that's not a legal name. Commented Dec 21, 2021 at 14:31

1 Answer 1

1

This XPath,

//*[local-name()='text']/@value

will select all of the value attributes of all text elements in the document, regardless of namespaces.

Note that it is better to account for namespaces than to defeat them in this manner. See How does XPath deal with XML namespaces?


Not working?

The provided XPath does select both @value attributes. If you're only seeing one, it's likely because you're passing the result on to an XPath 1.0 function that expects a single value and is defined to select the first member of a node-set when passed multiple values. See Why does XPath expression only select text of first element?


Still not working?

Here are two options for selecting the values individually rather than collectively:

  1. (//*[local-name()='text']/@value)[1]
    (//*[local-name()='text']/@value)[2]

  2. //*[local-name()='substance']/*[local-name()='text']/@value
    //*[local-name()='makers']/*[local-name()='text']/@value

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks it worked for the first /substance/text and I need to extract the value from /makers/text as well. How we can give the parent node in start?
Actually I am storing each value into a variable and hence //*[local-name()='text']/@value returns Automation and stored in variable so now I have to get the second value somehow. Is there a way to pass the parent node in this expression?
Some how both above options are not working. Option 2 didn't work at all while for option 1 when I changed the array to Option 1: (//*[local-name()='text']/@value)[1] and (//*[local-name()='text']/@value)[2] it worked for [1] but not for [2].
See updated answer. If the shown options are still not working for you, I suspect there's a difference between your posted and actual XML or an issue in how you're using the results returned by the XPath expressions.
Thanks for your help. It is working fine I had one mistake in my code so once I corrected it started working

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.