Get all included stylesheets

2019-07-16 08:50发布

It is possible to get a list of all included stylesheets within the xslt process?

I ask because the whole include/import process is done before the execution and I wonder if I have access to this information?

标签: xslt
2条回答
三岁会撩人
2楼-- · 2019-07-16 09:05

This short and fully generic transformation produces a hierarchical result (XML tree) that presents all imports/inclusions in any stylesheet tree and avoids infinite loops. Do note that XSLT (both 1.0 and 2.0) allows circular imports.

<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:param name="pUri" select="'test-strSplitWordDel2.xsl'"/>
 <xsl:variable name="vVisited" select="'|'"/>

 <xsl:template match="/">
  <xsl:param name="pUri" select="$pUri"/>
  <xsl:param name="pVisited" select="$vVisited"/>

  <xsl:variable name="vVisited" select="concat($pVisited, $pUri, '|')"/>

  <stylesheet uri="{$pUri}">
   <xsl:if test="not(contains($pVisited, concat('|',$pUri,'|')))">
       <xsl:apply-templates select="*/xsl:import|*/xsl:include">
        <xsl:with-param name="pVisited" select="$vVisited"/>
       </xsl:apply-templates>
   </xsl:if>
  </stylesheet>
 </xsl:template>

 <xsl:template match="xsl:import|xsl:include">
   <xsl:param name="pVisited"/>
     <xsl:element name="{local-name()}">
       <xsl:apply-templates select="document(@href)">
        <xsl:with-param name="pUri" select="string(@href)"/>
        <xsl:with-param name="pVisited" select="$pVisited"/>
       </xsl:apply-templates>
     </xsl:element>
 </xsl:template>
</xsl:stylesheet>

For example, when we apply this transformation to the following FXSL stylesheet (func-standardXpathFunctions.xsl):

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:xdt="http://www.w3.org/2005/04/xpath-datatypes"
 xmlns:xdtOld="http://www.w3.org/2005/02/xpath-datatypes"
 xmlns:xdtOld2="http://www.w3.org/2004/10/xpath-datatypes"
 xmlns:f="http://fxsl.sf.net/"
 exclude-result-prefixes="xs xdt f"
>
<!--
       This module contains the FXSL versions of the "standard" XPath functions

       These are intended as convenience functions, so that they can be passed
       as parameters to other functions (e.g. to f:zipWith())
       or curried and passed as parameters (e.g. to f:map())
-->

 <xsl:import href="func-curry.xsl"/>
 <xsl:import href="func-compose-flist.xsl"/>

 <xsl:import href="func-standardArithmeticXpathFunctions.xsl"/>
 <xsl:import href="func-standardBooleanXpathFunctions.xsl"/>
 <xsl:import href="func-standardStringXpathFunctions.xsl"/>
 <xsl:import href="func-standardNodesXpathFunctions.xsl"/>
 <xsl:import href="func-standardSequencesXpathFunctions.xsl"/>
 <xsl:import href="func-standardAggregateXpathFunctions.xsl"/>
 <xsl:import href="func-standardDateTimeXpathFunctions.xsl"/>
 <xsl:import href="func-standardXSLTXpathFunctions.xsl"/>
 <xsl:import href="func-standardAxisXpathFunctions.xsl"/>

</xsl:stylesheet>

the wanted, correct result is produced:

<stylesheet uri="test-strSplitWordDel2.xsl">
   <import>
      <stylesheet uri="func-curry.xsl">
         <import>
            <stylesheet uri="../f/func-type.xsl">
               <import>
                  <stylesheet uri="../f/func-XpathConstructors.xsl">
                     <import>
                        <stylesheet uri="func-compose-flist.xsl">
                           <import>
                              <stylesheet uri="func-apply.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
               <import>
                  <stylesheet uri="../f/func-curry.xsl">
                     <import>
                        <stylesheet uri="../f/func-type.xsl"/>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-compose-flist.xsl">
         <import>
            <stylesheet uri="func-apply.xsl"/>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardArithmeticXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-curry.xsl">
               <import>
                  <stylesheet uri="../f/func-type.xsl">
                     <import>
                        <stylesheet uri="../f/func-XpathConstructors.xsl">
                           <import>
                              <stylesheet uri="func-compose-flist.xsl">
                                 <import>
                                    <stylesheet uri="func-apply.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                     <import>
                        <stylesheet uri="../f/func-curry.xsl">
                           <import>
                              <stylesheet uri="../f/func-type.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
         <import>
            <stylesheet uri="func-compose-flist.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardBooleanXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-curry.xsl">
               <import>
                  <stylesheet uri="../f/func-type.xsl">
                     <import>
                        <stylesheet uri="../f/func-XpathConstructors.xsl">
                           <import>
                              <stylesheet uri="func-compose-flist.xsl">
                                 <import>
                                    <stylesheet uri="func-apply.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                     <import>
                        <stylesheet uri="../f/func-curry.xsl">
                           <import>
                              <stylesheet uri="../f/func-type.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
         <import>
            <stylesheet uri="func-compose-flist.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardStringXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-curry.xsl">
               <import>
                  <stylesheet uri="../f/func-type.xsl">
                     <import>
                        <stylesheet uri="../f/func-XpathConstructors.xsl">
                           <import>
                              <stylesheet uri="func-compose-flist.xsl">
                                 <import>
                                    <stylesheet uri="func-apply.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                     <import>
                        <stylesheet uri="../f/func-curry.xsl">
                           <import>
                              <stylesheet uri="../f/func-type.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
         <import>
            <stylesheet uri="func-compose-flist.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardNodesXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-curry.xsl">
               <import>
                  <stylesheet uri="../f/func-type.xsl">
                     <import>
                        <stylesheet uri="../f/func-XpathConstructors.xsl">
                           <import>
                              <stylesheet uri="func-compose-flist.xsl">
                                 <import>
                                    <stylesheet uri="func-apply.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                     <import>
                        <stylesheet uri="../f/func-curry.xsl">
                           <import>
                              <stylesheet uri="../f/func-type.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
         <import>
            <stylesheet uri="func-compose-flist.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardSequencesXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-curry.xsl">
               <import>
                  <stylesheet uri="../f/func-type.xsl">
                     <import>
                        <stylesheet uri="../f/func-XpathConstructors.xsl">
                           <import>
                              <stylesheet uri="func-compose-flist.xsl">
                                 <import>
                                    <stylesheet uri="func-apply.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                     <import>
                        <stylesheet uri="../f/func-curry.xsl">
                           <import>
                              <stylesheet uri="../f/func-type.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
         <import>
            <stylesheet uri="func-compose-flist.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardAggregateXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-curry.xsl">
               <import>
                  <stylesheet uri="../f/func-type.xsl">
                     <import>
                        <stylesheet uri="../f/func-XpathConstructors.xsl">
                           <import>
                              <stylesheet uri="func-compose-flist.xsl">
                                 <import>
                                    <stylesheet uri="func-apply.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                     <import>
                        <stylesheet uri="../f/func-curry.xsl">
                           <import>
                              <stylesheet uri="../f/func-type.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
         <import>
            <stylesheet uri="func-compose-flist.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardDateTimeXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-curry.xsl">
               <import>
                  <stylesheet uri="../f/func-type.xsl">
                     <import>
                        <stylesheet uri="../f/func-XpathConstructors.xsl">
                           <import>
                              <stylesheet uri="func-compose-flist.xsl">
                                 <import>
                                    <stylesheet uri="func-apply.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                     <import>
                        <stylesheet uri="../f/func-curry.xsl">
                           <import>
                              <stylesheet uri="../f/func-type.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardXSLTXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-map.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
               <import>
                  <stylesheet uri="func-curry.xsl">
                     <import>
                        <stylesheet uri="../f/func-type.xsl">
                           <import>
                              <stylesheet uri="../f/func-XpathConstructors.xsl">
                                 <import>
                                    <stylesheet uri="func-compose-flist.xsl">
                                       <import>
                                          <stylesheet uri="func-apply.xsl"/>
                                       </import>
                                    </stylesheet>
                                 </import>
                              </stylesheet>
                           </import>
                           <import>
                              <stylesheet uri="../f/func-curry.xsl">
                                 <import>
                                    <stylesheet uri="../f/func-type.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
         <import>
            <stylesheet uri="func-flip.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
               <import>
                  <stylesheet uri="func-curry.xsl">
                     <import>
                        <stylesheet uri="../f/func-type.xsl">
                           <import>
                              <stylesheet uri="../f/func-XpathConstructors.xsl">
                                 <import>
                                    <stylesheet uri="func-compose-flist.xsl">
                                       <import>
                                          <stylesheet uri="func-apply.xsl"/>
                                       </import>
                                    </stylesheet>
                                 </import>
                              </stylesheet>
                           </import>
                           <import>
                              <stylesheet uri="../f/func-curry.xsl">
                                 <import>
                                    <stylesheet uri="../f/func-type.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
   <import>
      <stylesheet uri="func-standardAxisXpathFunctions.xsl">
         <import>
            <stylesheet uri="func-curry.xsl">
               <import>
                  <stylesheet uri="../f/func-type.xsl">
                     <import>
                        <stylesheet uri="../f/func-XpathConstructors.xsl">
                           <import>
                              <stylesheet uri="func-compose-flist.xsl">
                                 <import>
                                    <stylesheet uri="func-apply.xsl"/>
                                 </import>
                              </stylesheet>
                           </import>
                        </stylesheet>
                     </import>
                     <import>
                        <stylesheet uri="../f/func-curry.xsl">
                           <import>
                              <stylesheet uri="../f/func-type.xsl"/>
                           </import>
                        </stylesheet>
                     </import>
                  </stylesheet>
               </import>
            </stylesheet>
         </import>
         <import>
            <stylesheet uri="func-compose-flist.xsl">
               <import>
                  <stylesheet uri="func-apply.xsl"/>
               </import>
            </stylesheet>
         </import>
      </stylesheet>
   </import>
</stylesheet>
查看更多
虎瘦雄心在
3楼-- · 2019-07-16 09:18

This stylesheet (Main.xslt)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

   <xsl:include href="Sub1.xslt"/>
   <xsl:include href="Sub2.xslt"/>

   <xsl:template match="/">
      <root>
         <xsl:value-of select="document('Main.xslt')/xsl:stylesheet/xsl:include/@href"/>
      </root>
   </xsl:template>
</xsl:stylesheet>

with its included stylesheets Sub1.xslt and Sub2.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template name="Template1">
      <xsl:text>Template 1</xsl:text>
    </xsl:template>
</xsl:stylesheet>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template name="Template2">
      <xsl:text>Template 2</xsl:text>
    </xsl:template>
</xsl:stylesheet>

will produce

<?xml version="1.0" encoding="UTF-8"?>
<root>Sub1.xslt Sub2.xslt</root>

There may be a different way of doing it; I'm not sure. Also I'm not 100% sure of how the base URI is defined when calling document('Main.xslt'), meaning the file name could be resolved relative to the XML instance when you expect it to resolve relative to the XSLT file. In any case, I ran a test with an XML instance residing in a different directory than Main.xslt, and it still worked.

Addendum:

For walking the tree recursively, you can do something like this (XSLT1):

   <xsl:include href="Sub1.xslt"/>
   <xsl:include href="Sub2.xslt"/>

   <xsl:template match="/">
      <root>
         <xsl:call-template name="WalkIncludes">
            <xsl:with-param name="FileName" select="'Main.xslt'"/>
         </xsl:call-template>
      </root>
   </xsl:template>

   <xsl:template name="WalkIncludes">
      <xsl:param name="FileName"/>

         <xsl:for-each select="document($FileName)/xsl:stylesheet/xsl:include/@href">
            <xsl:value-of select="."/>

            <xsl:call-template name="WalkIncludes">
               <xsl:with-param name="FileName" select="."/>
            </xsl:call-template>
         </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>
查看更多
登录 后发表回答