从导入的.xsl文件显式调用命名模板

问题描述

我遇到以下情况:
我正在使用第三方xsl模板系统(kosit XRechnung),该系统允许通过指定自己的.xsl文件作为处理入口点来配置自定义适应。

流程如下:

+--------+                                         
|        |                                         
|        |                                         
|        |                                         
| in.xml |                                         
|        |                                         
+--------+                                         
    |                                              
    |                                              
    |                                              
    V                                              
+--------+                                         
|        |                                         
|        |  import   +--------+                    
| my.xsl | <-------- |        |                    
|        |           | adapt  |  import +---------+
|        |           |  .xsl  | <-------|         |
+--------+           |        |         | default |
    |                |        |         |  .xsl   |
   -|                +--------+         |         |
    |                                   |         |
    V                                   +---------+
+--------+                                         
|        |                                         
|        |                                         
|   out  |                                         
|  .xml  |                                         
|        |                                         
+--------+                                         

my.xsl是由我提供的一些.xml数据提供的处理入口点 adapt.xsl是一种改编,提供了一个命名模板,该模板有时被
调用 default.xsl会做很多事情来创建最终的输出XML文档。

default.xsl:

<!-- ... -->
        <xsl:when test="s:scenario">
          <rep:scenarioMatched>
            <xsl:apply-templates select="s:scenario" mode="copy" />
            <xsl:call-template name="documentData" />
            <xsl:sequence select="$validationStepResults" />
          </rep:scenarioMatched>
        </xsl:when>
<!-- ... -->

adapt.xsl:

<!-- Overwritten (default.xsl) -->
<xsl:template name="documentData">
    <rep:documentData>
        <xsl:for-each select="
            $input-document/*/cac:AccountingsupplierParty/cac:Party/cac:PartyLegalEntity/cbc:RegistrationName,$input-document/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeAgreement/ram:SellerTradeParty/ram:Name">
            <seller>
                <xsl:value-of select="."/>
            </seller>
        </xsl:for-each>
        
        <xsl:for-each select="
            $input-document/*/cbc:ID,$input-document/rsm:CrossIndustryInvoice/rsm:ExchangedDocument/ram:ID">
            <id>
                <xsl:value-of select="."/>
            </id>
        </xsl:for-each>
        
        <xsl:for-each select="$input-document/*/cbc:IssueDate,$input-document/rsm:CrossIndustryInvoice/rsm:ExchangedDocument/ram:IssueDateTime/udt:DateTimeString">
            <issueDate>
                <xsl:value-of select="."/>
            </issueDate>
        </xsl:for-each>
    </rep:documentData>
</xsl:template>

现在在我的顶级.xsl中,我可以再次覆盖在default.xsl调用的命名模板:

my.xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:rep="http://www.xoev.de/de/validator/varl/1"
    xmlns:s="http://www.xoev.de/de/validator/framework/1/scenarios" 
    xmlns:in="http://www.xoev.de/de/validator/framework/1/createreportinput"
    xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    xmlns:html="http://www.w3.org/1999/xhtml"
    xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" 
    xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
    xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
    xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessinformationEntity:100"
    xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
    xmlns:myns="urn:mycompany:xrechnung:data:enhancements"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:import href="./adapt.xsl"/>

    <xsl:output method="xml" indent="yes"/>

    <!-- Overwritten (default.xsl) -->
    <xsl:template name="documentData">
        <rep:documentData>
            <myns:MyContainer>
                <myns:MyElement>
                   <!-- Enhanced stuff -->
                </myns:MyElement>
            </myns:MyContainer>
            <!-- xsl:call-template name="documentData"/-->
        </rep:documentData>
    </xsl:template>
</xsl:stylesheet>

问题是:

如何在不复制adapt.xsl命名模板的xsl代码的情况下应用documentData中定义的内容(而不更改default.xsladapt.xsl)?

strong>

解决方法

在XSLT 3软件包的上下文中,这是可能的,请参见https://www.w3.org/TR/xslt-30/#refer-to-overridden

在一个命名模板中,该模板显示为xsl:override的子代,名称为 xsl:original可能显示为的名称属性的值 xsl:call-template:例如<xsl:call-template name="xsl:original"/>

Saxon 9.8和更高版本支持带有软件包的XSLT 3。

对于具体示例,我认为您需要使用第四个文件(例如adapt-package-wrapper.xsl),该文件是导入adapt.xsl的命名包,例如

<xsl:package xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
    name="http://example.com/adapt1" package-version="1.0">
    
    <xsl:expose component="template" names="documentData" visibility="public"/>
    
    <xsl:import href="adapt.xsl"/>
    
</xsl:package>

然后在my.xsl中,您需要声明覆盖:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    
    <xsl:use-package name="http://example.com/adapt1" version="1.0">
        <xsl:override>
          <xsl:template name="documentData">
            <rep:documentData>
              <myns:MyContainer>
                <myns:MyElement>
                   <!-- Enhanced stuff -->
                </myns:MyElement>
              </myns:MyContainer>
              <!-- xsl:call-template name="documentData"/-->
              <xsl:call-template name="xsl:original"/>
             </rep:documentData>
          </xsl:template>
        </xsl:override>
    </xsl:use-package>
    
    ...

</xsl:stylesheet>

然后,主要问题是让Saxon知道如何在命令行上使用以下方式将软件包名称http://example.com/adapt1映射到软件包文件: -lib:adapt-package-wrapper.xsl。或者,您可以使用配置文件。不确定是否可以在您的环境中做到这一点。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...