xslt - 从导入的 .xsl 文件中显式调用命名模板
问题描述
我有以下情况:
我正在使用第 3 方 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 文档。
默认.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>
<!-- ... -->
适应.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
:
我的.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
不复制documentData
命名模板的 xsl 代码的情况下应用定义的内容(不更改default.xsl
or adapt.xsl
)?
解决方案
在 XSLT 3 包的上下文中,这是可能的,请参阅https://www.w3.org/TR/xslt-30/#refer -to-overridden :
在作为 xsl:override 的子项出现的命名模板中,名称
xsl:original
可能显示为 xsl:call-template 的 name 属性的值:例如,<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
. 或者,您可以使用配置文件。不确定您是否可以在您的环境中执行此操作。
推荐阅读
- python - 如果我断开连接,Google Colab 会继续运行单元以将文件保存在已安装的驱动器中吗?
- postgresql - 是否可以每月添加每种类型的累积总和?
- openlayers - 如何在openLayers的折线中添加样式?
- css - 从 mat-form-field 中填充和删除边距的正确方法
- linker - 在 Uno WASM 中序列化 JSON 时“找不到构造函数”
- mysql - Mysql查询特定日期和时间范围
- python-3.x - 如何在 pyTelegramBotApi 中制作自定义 callback_data?
- java - 我获取数据但无法在 textview 中显示数据
- swift - swift中的多任务处理功能
- python - 如何更改神经网络中的 dtype