#xslt #import #xslt-2.0 #saxon
#xslt #импорт #xslt-2.0 #саксонский
Вопрос:
У меня следующая ситуация:
Я использую стороннюю систему шаблонов 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>
<!-- ... -->
адаптация.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.xsl
или adapt.xsl
)?
Комментарии:
1. Я не уверен, что правильно понял ваш вопрос, но чтобы избежать конфликтов имен, вы можете использовать пространства имен. Возможно, эта ссылка действительно помогает.
2. @zx485 Ну, я, очевидно, не очень хорошо разбираюсь в XSLT. «вы можете использовать пространства имен» Как так, не меняя ни
default.xsl
, ниadapt.xsl
?3. Шаги будут следующими: 1) Создайте пространство имен с
xslns:some="http:///..."
помощью «) Используйте его,adapt.xslt
чтобы изменить его на<xsl:template name="some:documentData">
3) Вызовите этоmy.xslt
с<xsl:call-template name="some:documentData">
помощью . Вы должны повторить decl пространстваmy.xslt
имен .4. @zx485 Я обновил свой вопрос с полным содержанием
my.xsl
, если вы будете так любезны и объясните шаги, которые мне нужно сделать там, создание другого пространства имен не будет проблемой.5. @zx485 Ну, как уже упоминалось: я не хочу / не могу меняться
adapt.xsl
. Но спасибо за ваши усилия.
Ответ №1:
В контексте пакетов XSLT 3 это возможно, см. https://www.w3.org/TR/xslt-30/#refer-to-overridden:
В именованном шаблоне, отображаемом как дочерний элемент xsl:override, имя
xsl:original
может отображаться как значение атрибута name 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
. Или вы можете использовать файл конфигурации. Не уверен, сможете ли вы сделать это в своей среде.
Комментарии:
1. Полезно знать. Я использую последнюю стабильную версию saxon. Я попробую это завтра. Пока нет.