259

I have following XML.

<?xml version="1.0" encoding="UTF-8"?>
<Employees>
    <Employee id="3">
        <age>40</age>
        <name>Tom</name>
        <gender>Male</gender>
        <role>Manager</role>
    </Employee>
    <Employee id="4">
        <age>25</age>
        <name>Meghna</name>
        <gender>Female</gender>
        <role>Manager</role>
    </Employee>
</Employees>

I want to select Employee element with id="4".

I am using below XPath expression which is not returning anything.

//Employee/[@id='4']/text()

I checked it at http://chris.photobooks.com/xml/default.htm and it says invalid xpath, not sure where is the issue.

4 Answers 4

368

You need to remove the / before the [. Predicates (the parts in [..]) shouldn't have slashes immediately before them - they go directly after the node selector they are associated with.

Also, to select the Employee element itself, you should leave off the /text() at the end. Otherwise you'd just be selecting the whitespace text values immediately under the Employee element.

//Employee[@id = '4']

One more thing to note: // can be very slow because it searches the entire document for matching nodes. If the structure of the documents you're working with is going to be consistent, you are probably best off using a more explicit path, for example:

/Employees/Employee[@id = '4']
Sign up to request clarification or add additional context in comments.

3 Comments

Note that // selects and searches over all nodes of the document which can be slow. Instead, if the structure of the document is known then use a proper path, like suggested in Gilles' answer below.
@Jens Yes, that's absolutely true. I've edited my answer to add an addendum.
"// can be very slow. Yes it can. It can also be very fast. It all depends on the XPath processor, the optimisations it applies, and the data structures it uses.
32

As a follow on, you could select "all nodes with a particular attribute" like this:

//*[@id='4']

Comments

12

Try doing this :

/Employees/Employee[@id=4]/*/text()

3 Comments

does xmllint loads the whole xml file into memory before looking for the ids?. I have a xml file of 46 GB and I am looking for ids in it
xml file of 46 GB - there is the problem.
--stream : use the streaming interface to process very large files
0

This snippet open a Web.Config file and return the value of a setting attribute by the name of attribute, with a single XPath

Dim origDoc As Xml.XmlDocument = New Xml.XmlDocument()
origDoc.Load(WebConfigFile)
Dim settingNode As Xml.XmlNode = origDoc.SelectSingleNode("/configuration/appSettings/add[@key='" + SettingName + "']/@value")
If settingNode Is Nothing Then Return Nothing
Return settingNode.Value

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.