Использование итерации в XSLT - PullRequest
2 голосов
/ 18 января 2012

У меня есть следующий 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 голосов
/ 18 января 2012

I.Решение 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...