Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

xpath help

Status
Not open for further replies.

jba6511

Programmer
Jun 15, 2007
23
US
I am working on xpath and have some questions. I have the following document:

<?xml version='1.0'?>
<stores>
<store name='Red'>
<computers>
<computer>Dell</computer>
</cpmputers>
</store>
<store name='Green'>
<computers>
</computers>
<features>
<feature>Remote</feature>
</features>
</store>
</stores>

I want to select the name of the store that has feature "Remote" only. I have tried the following, but can not get it to work:

<xsl:value-of select="@name[/features/feature='Remote']"/>

I have only seen example using > or <. How do you use xpath to match characters or strings, such as Remote?
 
You may have missed this near the end of your previous thread426-1378857, where tsuji gave you a clue. For each leaf on an XPath expression you may apply a predicate that constrains the nodes selected at that leaf level. For this example, you would code:
Code:
<xsl:value-of select="stores/store[features/feature/text()='Remote']/@name"/>
This may be read as: Select the value(s) of the attribute name on the <store> element(s) which have a subordinate element value in features/feature equal to 'Remote'. You have to apply the constraint on the leaf of the XPath expression where the constraint makes sense. In your attempt, you were applying a constraint on the leaf specifying the attribute. I find this confusion often occurs. I speculate that programmers are not used to being able to declare predicate(s) in this way, though it makes perfect sense, and is quite powerful.

Also, for a second time, I will admonish you that, while your current XML processor may be forgiving the use of apostrophe on attribute values, do not expect that treatment from all XML processors!

Tom Morrison
 
It is still not outputting correctly. Is this correct?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl=" <xsl:eek:utput method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="storess">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="store">
<p>
<xsl:value-of select="stores/store[features/feature/text()='Remote']/@name"/>
</p>
</xsl:template>
</xsl:stylesheet>
 
Since you have the context node being "store", you have to adjust the line as Tom suggested. In the meantime, there are some refined detail you've to pay attention.

[1] Solution 1
[tt] <xsl:value-of select="@name[parent::*/features/feature/text()='Remote']"/>[/tt]
[2] Solution 2
[tt] <xsl:value-of select="self::*[features/feature/text()='Remote']/@name"/>[/tt]

But both of the solutions will result in empty <p /> for those no having "Remote" as a feature.

If you don't want even the empty <p/> to appear, you can make your template more selective.

[3] Solution 3
[tt]<xsl:template match="store[features/feature/text()='Remote']">
<p>
<xsl:value-of select="@name" />
</p>
</xsl:template>
[/tt]
 
solution 1 worked. Let me see if I understand whats happening though. It is saying select all the name, look through all the child nodes (is that what the ::* is for) to find node features then feature whos thext is equal to Remote?
 
tsuji may be sleeping by now, so I will try to help.

In solution 1, the first leaf of the predicate expression (the thing inside the [ ]) is [tt]parent::*[/tt]. So, this means, "all the nodes on the parent axis of the attribute node (@name)." Now the parent axis can contain zero or one nodes, which can be useful in detecting when a node has no parent (but that is a differnt lesson); [tt]parent::*[/tt] gets you to that parent node which in this case certainly exists.

So, the predicate expression says, "Select all the name attribute nodes named name for which the condition 'the parent of the attribute node contains a child node named features which in turn contains a child node named feature the text value of which is Remote' is true".

Just typing that explanation makes me glad we have XPath!

Tom Morrison
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top