1

I'm trying to use xpath to query for a particular email address in the following XML.

<?xml version="1.0"?>
<records>
        <record>
          <f id="6">sample data 1</f>
          <f id="7">user full name 1</f>
          <f id="8">first name 1</f>
          <f id="9">phone number 1</f>
          <f id="10">[email protected]</f>
          <f id="11">user1 last name</f>
          <f id="12">url 1</f>
        </record>
        <record>
          <f id="6">sample data 2</f>
          <f id="7">user full name 2</f>
          <f id="8">first name 2</f>
          <f id="9">phone number 2</f>
          <f id="10">[email protected]</f>
          <f id="11">user2 last name</f>
          <f id="12">url 2</f>
        </record>
        <record>
          <f id="6">sample data 3</f>
          <f id="7">user full name 3</f>
          <f id="8">first name 3</f>
          <f id="9">phone number 3</f>
          <f id="10">[email protected]</f>
          <f id="11">user3 last name</f>
          <f id="12">url 3</f>
        </record>
      </records>

I'm using PHP and so far I'm able to query for ALL the email addresses by the following line.

$result = $xml->xpath('/records/record/f[@id="10"]');

However, I want to be able to query for a particular email address, e.g. "[email protected]". Can this be done all in one line with xpath?

Also, I need to return some of the other values in the XML based on that email address.

For example, I'd query the XML for "[email protected]" and then return "user full name 2", "sample data 2", etc.

Any help would be appreciated! I'm relatively new to xpath and after trying to look through examples on W3C schools I'm coming up short.

2 Answers 2

2

This would give you the respective <record>:

$xml->xpath('/records/record[f[@id="10"] = "[email protected]"]');

Note that predicates can be nested.


A little more interesting is this, which would also give you the respective <record>

$xml->xpath('/records/record[f = "[email protected]"]');

This works because the XPath = operator compares all matching nodes to the right-hand value. You could read it as "…where any <f> has a value of '[email protected]'.".

Consequently the first expression reads as follows: "…where any <f> with an @id of 10 has a value of '[email protected]'.", i.e. if multiple <f> elements had an ID of 10, it would check them all.

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

Comments

0

You can also accomplish this with navigation instead of a nested predicate condition:

/records/record/f[@id=10 and text()='[email protected]']/..

This says, "navigate down to the fs, find the email address node matching this condition, then get the parent of the node (which is record)." From there you can navigate down to a particular f.

Comments

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.