开发者

what is current() in predicate of predicate

another XPath/XSL question :)

开发者_开发知识库If i have a node tree like:

A

-- B (anymal-types=pets)

---- C (type=bird)

---- C (type=cat)

---- C (type=dog)

-- B (working-animals)

---- C (type=cow)

---- C (type=elephant)

-A

...

and another xml file ($xmlFile) that lists types that one needs for the given anymal-type

-pet

---- cat

---- dog

-working-animal

----elephant

how do i select only these animals that the $xmlFile oders me to?:

what in this case current() refers to: - is it node that template matches on ("A") - or is it current C node being evaluated.

What would be the right way to get to the current C node being evaluated and step one node up (to B, that defines animal-type).

Thanks.


This transformation:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vrtfXmlFile">
     <pets>
       <animal>cat</animal>
       <animal>dog</animal>
     </pets>
     <working-animals>
       <animal>elephant</animal>
     </working-animals>
    </xsl:variable>

    <xsl:variable name="vxmlFile" select=
     "document('')/*/xsl:variable
                      [@name='vrtfXmlFile']"/>

 <xsl:template match="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="b">
   <xsl:if test="$vxmlFile/*[name()=current()/@animal-types]">
     <xsl:call-template name="identity"/>
   </xsl:if>
 </xsl:template>

 <xsl:template match="c">
  <xsl:if test=
    "$vxmlFile/*[name()=current()/../@animal-types]
                              /animal[.=current()/@type]">
   <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

<a>
 <b animal-types="pets">
   <c type="bird"/>
   <c type="cat"/>
   <c type="dog"/>
 </b>
 <b animal-types="working-animals">
   <c type="cow"/>
   <c type="elephant"/>
 </b>
</a>

produces the wanted, correct result:

<a>
   <b animal-types="pets">
      <c type="cat"/>
      <c type="dog"/>
   </b>
   <b animal-types="working-animals">
      <c type="elephant"/>
   </b>
</a>

Notes:

  1. For convenience, the second document containing the allowed animals, is incorporated in the XSLT stylesheet. In practice one would use the document(some-uri) function to read, parse and define this as the contents of the $vxmlFile variable.

  2. If the list of allowed animals is very long, then using Muenchian grouping (keys) would be significantly more efficient.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜