New to XML/XSL/Xpath, and I’ve scoured these boards for an answer to a seemingly simple problem, but maybe I’m too new to XSL to understand some of the answers out there that might address this.
I want to select a set of nodes that match a different set of node values stored elsewhere in the doc, so that:
<body>
<partlist>
<part>head</part>
<part>spleen</part>
<part>toe</part>
</partlist>
<parts>
<head>this is a head</head>
<spleen>this is a spleen</spleen>
<toe>big toe</toe>
<toe>big toe</toe>
<parts>
</body>
So that, let’s say I want to count all the “parts”, but I don’t know the “parts” node names, I would want an XPath expr to match a set of nodes whose names are equal to the values of another set of nodes…
I am new enough to XSL to both imagine that a solution is very simple, but experienced enough to realize that expecting a simple solution from XSL is a sure wrong path.
In my procedural-based ignorance, this is what I have tried:
<xsl:template match="/">
<xsl:apply-templates select="partlist/part">
<xsl:with-param name="parts" select="parts"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="part">
<xsl:param name="parts"/>
<xsl:value-of select="count($parts[.])"/>
</xsl:template>
But this is completely wrong. Any help is much appreciated.
Edit: Thanks for the answers, but I think I’m not being understood – the fault is mine, because I haven’t been perfectly clear… What I need is a single result telling me if there are ANY nodes that match the node value of the referring set… that I think changes the query, because I’m not trying to output a list of counts, I’m trying to match a set against a set to count the total… but let me clarify with XSL, if such a thing is possible.. here’s my code from above, slightly modified to make my intention clear:
<xsl:template match="/">
<xsl:apply-templates select="partlist/part">
<xsl:with-param name="parts" select="parts"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="part">
<xsl:param name="parts"/>
<xsl:if select="count($parts[.]) > 0">1</xsl:if>
</xsl:template>
the above when applied to the xml doc example should output:
1
Does this make sense?
Edit: I should also specify that I am limited to XSL 1.0
You can use the
local-name()function to get the name of a node so you can compare it against a given value.For example, your stylesheet could be modified to this:
Edited to add:
You can also compare against sets of values instead of just single values. From XPath 1.0 spec, section 3.4:
If you want to count how many elements you have under
/body/partswhose local name matches the parts listed in/body/partlist/part, you could do it with this XPath expression:The last transformation from the question, added after the edit, could be rewritten for example like this: