Явный вызов именованного шаблона из импортированного файла .xsl

#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. Я попробую это завтра. Пока нет.