在XSLT中使用迭代

时间:2012-01-17 22:38:06

标签: xml xslt

我有以下XSLT:

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

  <xsl:template match="node()[child::node()
            [contains(@Source, 'filename1')
            or contains(@Source, 'filename2')]]" />

有人可以建议我如何使用参数或变量而不是“filename1”和“filename2”来循环文件链?

如何重写第二个模板(可能,添加新模板?)以使用内联xsl,例如

  <xsl:variable name="FileName">
    <name>filename1</name>
    <name>filename2</name>
  </xsl:variable>

提前致谢,

利奥

1 个答案:

答案 0 :(得分:0)

<强>予。 XSLT 1.0解决方案(这对XSLT 2.0来说更容易):

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

 <my:fileNames>
   <f>filename1</f>
   <f>filename2</f>
 </my:fileNames>

 <xsl:variable name="vFilenames"
               select="document('')/*/my:fileNames/*"/>

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

 <xsl:template match="node()">
  <xsl:variable name="vCur" select="."/>
  <xsl:variable name="vHit">
   <xsl:for-each select="$vFilenames">
    <xsl:if test=
     "$vCur/node()[contains(@Source, current())]">1</xsl:if>
   </xsl:for-each>
  </xsl:variable>
  <xsl:choose>
   <xsl:when test="not(string-length($vHit))">
    <xsl:call-template name="identity"/>
   </xsl:when>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

应用于此XML文档(您何时,人们,学习提供源XML?):

<t>
    <tt>
        <x>
            <y/>
        </x>
        <mm>
            <z Source="filename1">
                <u/>
                <v/>
            </z>
        </mm>
        <rr>
            <m Source="filename2">
                <u/>
                <v/>
            </m>
        </rr>
        <v-v>
            <p Source="filename3">
                <u/>
                <v/>
            </p>
        </v-v>
    </tt>
</t>

生成想要的正确结果

<t>
   <tt>
      <x>
         <y/>
      </x>
      <v-v>
         <p Source="filename3">
            <u/>
            <v/>
         </p>
      </v-v>
   </tt>
</t>

<强> II。 XSLT 2.0解决方案:

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

 <xsl:param name="pFileNames">
   <f>filename1</f>
   <f>filename2</f>
 </xsl:param>

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

 <xsl:template match=
  "node()[node()
          [some $fn in $pFileNames/f
            satisfies
              contains(@Source, $fn)
          ]
         ]"/>
</xsl:stylesheet>

将此转换应用于同一XML文档(如上所述)时,会生成相同的正确结果

<t>
   <tt>
      <x>
         <y/>
      </x>
      <v-v>
         <p Source="filename3">
            <u/>
            <v/>
         </p>
      </v-v>
   </tt>
</t>