[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
I have XML looking something like the following (it might be large with lots of services and nodes so performance can be a factor):
I'm going to pass an IP into the stylesheet and do a node (on elements named node) lookup based on that. If the ip passed in is in none of the ranges it will default to the top node element. The thing I then want to render is two-fold.
1) I want to render all services that is referenced by all <service ref="..."/> in the <node/> found with the IP and all <service/> elements in all parent <node/> elements. This is easy with ancestor-or-self and some loop.
2) I want to render the categories and and their <service/> elements where all <service/> elements not selected in 1) is excluded. If a category ends up with no service element it should be totally left out.
An ip that is outside of the ranges specified should render a document similar to the following (structure wise anyway):
I currently have the following but it uses node-set() in the category template and I don't want that (it will force me to do multiple loops as well when I want the "real" output). Is there another solution?
<xsl:param name="ip_param" select="'555555555555'"/>
<xsl:variable name="ip" select="number($ip_param)"/>
<xsl:variable name="selectedNode" select="/docroot/nodes//node[@id=$selectedNodeId]"/>
<xsl:variable name="selectedServices" select="$selectedNode/ancestor-or-self::node/services/service"/>
</xsl:stylesheet>
Any help is appreciated (optimizing as well)
/Marcus
Selecting (and excluding) nodes
Subject: Selecting (and excluding) nodes From: Marcus Andersson <marcus@xxxxxxxxxx> Date: Tue, 22 Jun 2004 16:55:58 +0200 |
I have XML looking something like the following (it might be large with lots of services and nodes so performance can be a factor):
<docroot> <services> <service id="842" name="service1"/> <service id="843" name="service2"/> <service id="844" name="service3"/> <service id="845" name="service4"/> </services>
<categories> <section> <category name="cat1"> <service ref="842"/> <service ref="844"/> </category> <category name="cat2"> <service ref="842"/> <service ref="843"/> <service ref="845"/> </category> <category name="cat3"> <service ref="843"/> </category> </section> </categories>
<node> <node> <services> <service ref="842"/> <service ref="844"/> <service ref="845"/> </services> <node> <ipranges> <range from="111111111111" to="222222222222"/> <range from="333333333333" to="444444444444"/> </ipranges> <services> <service ref="843"/> </service> </node> </node> </nodes> </docroot>
I'm going to pass an IP into the stylesheet and do a node (on elements named node) lookup based on that. If the ip passed in is in none of the ranges it will default to the top node element. The thing I then want to render is two-fold.
1) I want to render all services that is referenced by all <service ref="..."/> in the <node/> found with the IP and all <service/> elements in all parent <node/> elements. This is easy with ancestor-or-self and some loop.
2) I want to render the categories and and their <service/> elements where all <service/> elements not selected in 1) is excluded. If a category ends up with no service element it should be totally left out.
An ip that is outside of the ranges specified should render a document similar to the following (structure wise anyway):
<result> <items> <item id="842" name="service1"/> <item id="843" name="service2"/> <item id="844" name="service3"/> <item id="845" name="service4"/> </items>
<categories> <category name="cat1"> <item ref="842"/> <item ref="844"/> </category> <category name="cat2"> <item ref="842"/> <item ref="845"/> </category> </categories> </result>
I currently have the following but it uses node-set() in the category template and I don't want that (it will force me to do multiple loops as well when I want the "real" output). Is there another solution?
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:param name="ip_param" select="'555555555555'"/>
<xsl:variable name="ip" select="number($ip_param)"/>
<!-- The following three variables might replacable by just one. I haven't figured out how though. It's only $selectedNode that is interesting -->
<xsl:variable name="selectedNodeByIp" select="/docroot/nodes//node[ipranges/range[number(@from) <= $ip and $ip <= number(@to)]][1]"/>
<xsl:variable name="selectedNodeId"> <xsl:choose> <xsl:when test="$selectedNodeByIp"><xsl:value-of select="$selectedNodeByIp/@id"/></xsl:when> <xsl:otherwise><xsl:value-of select="/docroot/nodes/node[1]/@id"/></xsl:otherwise> </xsl:choose> </xsl:variable>
<xsl:variable name="selectedNode" select="/docroot/nodes//node[@id=$selectedNodeId]"/>
<xsl:variable name="selectedServices" select="$selectedNode/ancestor-or-self::node/services/service"/>
<xsl:template match="/docroot"> <docroot> <items> <xsl:for-each select="$selectedServices"> <item> <xsl:copy-of select="@*"/> </item> </xsl:for-each> </items> <categories> <xsl:apply-templates select="categories/section/category"/> </categories> </docroot> </xsl:template>
<xsl:template match="category"> <xsl:variable name="acat"> <category> <xsl:copy-of select="@*"/> <xsl:for-each select="service"> <xsl:if test="$selectedServices[@ref=current()/@ref]"> <item ref="{@ref}"/> </xsl:if> </xsl:for-each> </category> </xsl:variable> <xsl:variable name="cat" select="msxsl:node-set($acat)/category"/> <xsl:if test="count($cat/*) > 0"> <xsl:copy-of select="$cat"/> </xsl:if> </xsl:template>
</xsl:stylesheet>
Any help is appreciated (optimizing as well)
/Marcus
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] List of Unique Items with, Michael Kay | Thread | [xsl] conversion from xslt2.0 to xs, TDarksword |
List of Unique Items within an XML , Ben Gazzard | Date | RE: [xsl] List of Unique Items with, Kenny Akridge |
Month |
Keywords