2013-04-10 98 views
0

我有一个具有抽象模式的schematron文件,我想用一个xsl文件将这个文件转换为一个没有抽象模式的文件,所有的抽象模式都是实例。 的问题是,当我实例的抽象图案,如果我提供的<pattern>一切@id属性OK.wi​​thout的@ ID,paremeter的抽象图案不能正确替换 的Schematron的文件如下如何结合这两个xsl文件

<?xml version="1.0" encoding="UTF-8"?> 
<schema xmlns="http://purl.oclc.org/dsdl/schematron"> 
    <title>Table abstract patterns</title> 

    <pattern abstract="true" id="table"> 
     <rule context="$table"> 
      <assert test="$row">A table has at least one row</assert> 
     </rule> 
     <rule context="$row"> 
      <assert test="$cell">A table row has at least one cell</assert> 
     </rule> 
    </pattern> 

    <pattern is-a="table"> 
     <param name="table" value="table"/> 
     <param name="row" value="tr"/> 
     <param name="cell" value="td"/> 
    </pattern> 
</schema> 

XSL文件是

<xslt:stylesheet version="1.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:iso="http://purl.oclc.org/dsdl/schematron" 
    xmlns:nvdl="http://purl.oclc.org/dsdl/nvdl" 


    xmlns:iae="http://www.schematron.com/namespace/iae" 

     > 

    <xslt:param name="schema-id"></xslt:param> 


    <!-- Driver for the mode --> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="." mode="iae:go" /> 
    </xsl:template> 


    <!-- ================================================================================== --> 
    <!-- Normal processing rules               --> 
    <!-- ================================================================================== --> 
    <!-- Output only the selected schema --> 
    <xslt:template match="iso:schema" > 
     <xsl:if test="string-length($schema-id) =0 or @id= $schema-id "> 
      <xslt:copy> 
       <xslt:copy-of select="@*" /> 
       <xslt:apply-templates mode="iae:go" /> 
      </xslt:copy> 
     </xsl:if> 
    </xslt:template> 


    <!-- Strip out any foreign elements above the Schematron schema . 
     --> 
    <xslt:template match="*[not(ancestor-or-self::iso:*)]"  mode="iae:go" > 
     <xslt:apply-templates mode="iae:go" /> 
    </xslt:template> 


    <!-- ================================================================================== --> 
    <!-- Handle Schematron abstract pattern preprocessing         --> 
    <!-- abstract-to-real calls 
      do-pattern calls 
       macro-expand calls 
        multi-macro-expand 
         replace-substring             --> 
    <!-- ================================================================================== --> 

    <!-- 
     Abstract patterns allow you to say, for example 

     <pattern name="htmlTable" is-a="table"> 
      <param name="row" value="html:tr"/> 
      <param name="cell" value="html:td" /> 
      <param name="table" value="html:table" /> 
     </pattern> 

     For a good introduction, see Uche Ogbujii's article for IBM DeveloperWorks 
     "Discover the flexibility of Schematron abstract patterns" 
      http://www-128.ibm.com/developerworks/xml/library/x-stron.html 
     However, note that ISO Schematron uses @name and @value attributes on 
     the iso:param element, and @id not @name on the pattern element. 

    --> 

    <!-- Suppress declarations of abstract patterns --> 
    <xslt:template match="iso:pattern[@abstract='true']" mode="iae:go" > 
     <xslt:comment>Suppressed abstract pattern <xslt:value-of select="@id"/> was here</xslt:comment> 
    </xslt:template> 


    <!-- Suppress uses of abstract patterns --> 
    <xslt:template match="iso:pattern[@is-a]" mode="iae:go" > 

     <xslt:comment>Start pattern based on abstract <xslt:value-of select="@is-a"/></xslt:comment> 

     <xslt:call-template name="iae:abstract-to-real" > 
      <xslt:with-param name="caller" select="@id" /> 
      <xslt:with-param name="is-a" select="@is-a" /> 
     </xslt:call-template> 

    </xslt:template> 



    <!-- output everything else unchanged --> 
    <xslt:template match="*" priority="-1" mode="iae:go" > 
     <xslt:copy> 
      <xslt:copy-of select="@*" /> 
      <xslt:apply-templates mode="iae:go"/> 
     </xslt:copy> 
    </xslt:template> 

    <!-- Templates for macro expansion of abstract patterns --> 
    <!-- Sets up the initial conditions for the recursive call --> 
    <xslt:template name="iae:macro-expand"> 
     <xslt:param name="caller"/> 
     <xslt:param name="text" /> 
     <xslt:call-template name="iae:multi-macro-expand"> 
      <xslt:with-param name="caller" select="$caller"/> 
      <xslt:with-param name="text" select="$text"/> 
      <xslt:with-param name="paramNumber" select="1"/> 
     </xslt:call-template> 

    </xslt:template> 

    <!-- Template to replace the current parameter and then 
     recurse to replace subsequent parameters. --> 

    <xslt:template name="iae:multi-macro-expand"> 
     <xslt:param name="caller"/> 
     <xslt:param name="text" /> 
     <xslt:param name="paramNumber" /> 


     <xslt:choose> 
      <xslt:when test="//iso:pattern[@id=$caller]/iso:param[ $paramNumber]"> 

       <xslt:call-template name="iae:multi-macro-expand"> 
        <xslt:with-param name="caller" select="$caller"/> 
        <xslt:with-param name="paramNumber" select="$paramNumber + 1"/>  
        <xslt:with-param name="text" > 
         <xslt:call-template name="iae:replace-substring"> 
          <xslt:with-param name="original" select="$text"/> 
          <xslt:with-param name="substring" 
          select="concat('$', //iso:pattern[@id=$caller]/iso:param[ $paramNumber ]/@name)"/> 
          <xslt:with-param name="replacement" 
           select="//iso:pattern[@id=$caller]/iso:param[ $paramNumber ]/@value"/>   
         </xslt:call-template> 
        </xslt:with-param>      
       </xslt:call-template> 
      </xslt:when> 
      <xslt:otherwise><xslt:value-of select="$text" /></xslt:otherwise>  

     </xslt:choose> 
    </xslt:template> 


    <!-- generate the real pattern from an abstract pattern + parameters--> 
    <xslt:template name="iae:abstract-to-real" > 
     <xslt:param name="caller"/> 
     <xslt:param name="is-a" /> 
     <xslt:for-each select="//iso:pattern[@id= $is-a]"> 
     <xslt:copy> 

      <xslt:choose> 
       <xslt:when test=" string-length($caller) = 0"> 
       <xslt:attribute name="id"><xslt:value-of select="concat(generate-id(.) , $is-a)" /></xslt:attribute> 
       </xslt:when> 
       <xslt:otherwise> 
       <xslt:attribute name="id"><xslt:value-of select="$caller" /></xslt:attribute> 
       </xslt:otherwise> 
      </xslt:choose> 

      <xslt:apply-templates select="*|text()" mode="iae:do-pattern" > 
       <xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param> 
      </xslt:apply-templates> 

     </xslt:copy> 
     </xslt:for-each> 
    </xslt:template> 


    <!-- Generate a non-abstract pattern --> 
    <xslt:template mode="iae:do-pattern" match="*"> 
     <xslt:param name="caller"/> 
     <xslt:copy> 
      <xslt:for-each select="@*[name()='test' or name()='context' or name()='select']"> 
       <xslt:attribute name="{name()}"> 
       <xslt:call-template name="iae:macro-expand"> 
         <xslt:with-param name="text"><xslt:value-of select="."/></xslt:with-param> 
         <xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param> 
        </xslt:call-template> 
       </xslt:attribute> 
      </xslt:for-each>  
      <xslt:copy-of select="@*[name()!='test'][name()!='context'][name()!='select']" /> 
      <xsl:for-each select="node()"> 
       <xsl:choose> 
        <!-- Experiment: replace macros in text as well, to allow parameterized assertions 
         and so on, without having to have spurious <iso:value-of> calls and multiple 
         delimiting --> 
        <xsl:when test="self::text()"> 
         <xslt:call-template name="iae:macro-expand"> 
          <xslt:with-param name="text"><xslt:value-of select="."/></xslt:with-param> 
          <xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param> 
         </xslt:call-template> 
        </xsl:when> 
        <xsl:otherwise> 
         <xslt:apply-templates select="." mode="iae:do-pattern"> 
          <xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param> 
         </xslt:apply-templates>  
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:for-each>   
     </xslt:copy> 
    </xslt:template> 

    <!-- UTILITIES --> 
    <!-- Simple version of replace-substring function --> 
    <xslt:template name="iae:replace-substring"> 
     <xslt:param name="original" />  
     <xslt:param name="substring" /> 
     <xslt:param name="replacement" select="''"/> 

    <xsl:choose> 
    <xsl:when test="not($original)" /> 
    <xsl:when test="not(string($substring))"> 
     <xsl:value-of select="$original" /> 
    </xsl:when> 
     <xsl:when test="contains($original, $substring)"> 
      <xsl:variable name="before" select="substring-before($original, $substring)" /> 
      <xsl:variable name="after" select="substring-after($original, $substring)" /> 

      <xsl:value-of select="$before" /> 
      <xsl:value-of select="$replacement" /> 
      <!-- recursion --> 
      <xsl:call-template name="iae:replace-substring"> 
      <xsl:with-param name="original" select="$after" /> 
      <xsl:with-param name="substring" select="$substring" /> 
      <xsl:with-param name="replacement" select="$replacement" /> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <!-- no substitution --> 
      <xsl:value-of select="$original" /> 
     </xsl:otherwise> 
     </xsl:choose> 
</xslt:template> 

</xslt:stylesheet> 

我预期的结果是

<?xml version="1.0" encoding="UTF-8"?> 
<schema xmlns="http://purl.oclc.org/dsdl/schematron"> 
    <title>Table abstract patterns</title> 

    <pattern id="table1"> 
     <rule context="table"> 
      <assert test="tr">A table has at least one row</assert> 
     </rule> 
     <rule context="tr"> 
      <assert test="td">A table row has at least one cell</assert> 
     </rule> 
    </pattern> 
</schema> 

现在我有一个预处理XSL如下,如果我第一次用这个和明年上面的一个,我会得到我想要

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xslt="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"  
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:iso="http://purl.oclc.org/dsdl/schematron" 
    xmlns:nvdl="http://purl.oclc.org/dsdl/nvdl" 


    xmlns:iae="http://www.schematron.com/namespace/iae" 

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

    <xsl:template match="iso:pattern[not(@id)]"> 

     <xslt:comment>Add @id for pattern </xslt:comment> 
     <xsl:copy> 
      <xslt:comment>Add @id for pattern </xslt:comment> 
      <xsl:attribute name="id"> 
       <xslt:value-of select="generate-id(.) "/> 
      </xsl:attribute> 
      <xsl:apply-templates select="node() | @*"/> 
     </xsl:copy> 

    </xsl:template> 

</xsl:stylesheet> 

如何将这两个文件组合在一起呢?

回答

0

更改您的模板:

<xslt:template name="iae:abstract-to-real" > 
    <xslt:param name="caller"/> 
    <xslt:param name="is-a" /> 
    <xslt:for-each select="//iso:pattern[@id= $is-a]"> 
     <xslt:copy> 

     <xslt:choose> 
      <xslt:when test=" string-length($caller) = 0"> 
      <xslt:attribute name="id"><xslt:value-of select="concat(generate-id(.) , $is-a)"/></xslt:attribute> 
      </xslt:when> 
      <xslt:otherwise> 
      <xslt:attribute name="id"><xslt:value-of select="$caller" /></xslt:attribute> 
      </xslt:otherwise> 
     </xslt:choose> 

     <xslt:apply-templates select="*|text()" mode="iae:do-pattern" > 
      <xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param> 
     </xslt:apply-templates> 

     </xslt:copy> 
    </xslt:for-each> 
    <xslt:for-each select="//iso:pattern[not(@id)]"> 
     <xslt:copy> 

     <xslt:choose> 
      <xslt:when test=" string-length($caller) = 0"/> 
      <xslt:otherwise> 
      <xslt:attribute name="id"><xslt:value-of select="$caller" /></xslt:attribute> 
      </xslt:otherwise> 
     </xslt:choose> 

     <xslt:apply-templates select="*|text()" mode="iae:do-pattern" > 
      <xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param> 
     </xslt:apply-templates> 

     </xslt:copy> 
    </xslt:for-each> 
    </xslt:template> 
+0

谢谢你,但它不干活添加预期结果我的问题 – 2013-04-11 11:49:24