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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Advanced XML recursive searching via XSL - help required!

Status
Not open for further replies.

Clemintine

Programmer
Oct 9, 2001
7
0
0
GB
Hi,
Target : At any level where the text in @TITLE contains the searchterm 'Plate' select all child nodes of the found node and parent nodes of the found node, preserving the attributes.
There is a requirement to preserve the recursive quality of the current imperfect solution as the example xml is a much simpler version of the actual xml being used.

Problem : The XSL shown works perfectly well EXCEPT, when there is a parent AND child both containing the searchterm, the parents children that are siblings to the matching child don't show, somehow affected by the match on the child.
You can simulate this by altering the attribute TITLE in ITEM 'GM Crafted Female Plate' to 'GM Crafted Female'.
Top marks to any one who can answer this as I realise its not a simple one!

Sample XML:

<LINEDETAILS TITLE=&quot;Armour&quot;>
<EXPANSION TITLE=&quot;Shields&quot;>
<ITEM TITLE=&quot;GM Crafted Kite&quot; PRICE=&quot;200&quot;/>
<ITEM TITLE=&quot;GM Crafted Metal&quot; PRICE=&quot;150&quot;/>
<ITEM TITLE=&quot;GM Crafted Heater&quot; PRICE=&quot;250&quot;/>
<ITEM TITLE=&quot;GM Crafted Bronze&quot; PRICE=&quot;150&quot;/>
<ITEM TITLE=&quot;GM Crafted Small Kite&quot; PRICE=&quot;150&quot;/>
<ITEM TITLE=&quot;GM Crafted Buckler&quot; PRICE=&quot;100&quot;/>
</EXPANSION>
<EXPANSION TITLE=&quot;Helmets&quot;>
<ITEM TITLE=&quot;GM Crafted Bascinet&quot; PRICE=&quot;150&quot;/>
<ITEM TITLE=&quot;GM Crafted Nose Helm&quot; PRICE=&quot;200&quot;/>
<ITEM TITLE=&quot;GM Crafted Close Helm&quot; PRICE=&quot;200&quot;/>
<ITEM TITLE=&quot;GM Crafted Helm&quot; PRICE=&quot;180&quot;/>
<ITEM TITLE=&quot;GM Crafted Plate Helm&quot; PRICE=&quot;400&quot;/>
</EXPANSION>
<EXPANSION TITLE=&quot;Plate Mail&quot;>
<ITEM TITLE=&quot;GM Crafted Tunic&quot; PRICE=&quot;1000&quot;/>
<ITEM TITLE=&quot;GM Crafted Arms&quot; PRICE=&quot;500&quot;/>
<ITEM TITLE=&quot;GM Crafted Gloves&quot; PRICE=&quot;350&quot;/>
<ITEM TITLE=&quot;GM Crafted Gorget&quot; PRICE=&quot;250&quot;/>
<ITEM TITLE=&quot;GM Crafted Legs&quot; PRICE=&quot;850&quot;/>
<ITEM TITLE=&quot;GM Crafted Female Plate&quot; PRICE=&quot;650&quot;/>
</EXPANSION>
</LINEDETAILS>


XSL :

<xsl:stylesheet xmlns:xsl=&quot; version=&quot;1.0&quot; >
<xsl:template match=&quot;node()&quot;>
<xsl:choose>
<!-- if there are children with an TITLE attribute containing text 'Plate', copy node and recurse down the tree -->
<xsl:when test=&quot;descendant::node()[contains(@TITLE,'Plate')]&quot;>
<xsl:copy>
<xsl:copy-of select=&quot;@*&quot;/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:when>
<!-- if there is an ancestor-or-self with a TITLE attribute containing text 'Plate', copy entire branch -->
<xsl:when test=&quot;contains(@TITLE,'Plate')&quot;>
<xsl:copy-of select=&quot;self::node()&quot;/>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>


Kind Regards Clemintine!
 
Hi Clementine,

Your code 'fails' because the xsl:choose is an 'this OR this' statement. So if you have a child element where the attribute Title contains Plate, it skips the check for the parentnode.

Perhaps switching your xsl:when statements will solve your problem?? Thus, first checking if the ancestor or self contains the search phrase, if so: you copy the entire tree below. So checking on these nodes isn't neccessary anymore.

Jordi Reineman
 
Thx a lot Jordi!,
Indeed switching the ordeer solved the problem I'm glad it was such a simple alteration!
Kind Regards Clemintine!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top