将两个 xsl 文件合并到一个文件中的功能(续......)

发布于 2024-10-11 08:56:52 字数 12620 浏览 0 评论 0原文

这是我的问题的延续:

将两个 xsl 文件的功能合并到一个文件中(不是 xsl 导入或包含问题)


我必须将上述问题的解决方案 (xsl) 合并​​到下面的 xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">

 <xsl:template match="/">
    <Declaration>
      <Message>
        <Meduim>
          <xsl:value-of select="/Declaration/Message/Meduim"/>
        </Meduim>
        <MessageIdentifier>
          <xsl:value-of select="/Declaration/Message/MessageIdentifier"/>
        </MessageIdentifier>
        <ControlingAgencyCode>
          <xsl:value-of select="/Declaration/Message/ControlingAgencyCode"/>
        </ControlingAgencyCode>
        <AssociationAssignedCode>
          <xsl:value-of select="/Declaration/Message/AssociationAssignedCode"/>
        </AssociationAssignedCode>
        <CommonAccessReference>
          <xsl:value-of select="/Declaration/Message/CommonAccessReference"/>
        </CommonAccessReference>
      </Message>
      <BeginingOfMessage>
        <MessageCode>
          <xsl:value-of select="/Declaration/BeginingOfMessage/MessageCode"/>
        </MessageCode>
        <DeclarationCurrency>
          <xsl:value-of select="/Declaration/BeginingOfMessage/DeclarationCurrency"/>
        </DeclarationCurrency>
        <MessageFunction>
          <xsl:value-of select="/Declaration/BeginingOfMessage/MessageFunction"/>
        </MessageFunction>
      </BeginingOfMessage>
      <Header>
        <ProcessingInformation>
          <xsl:for-each select="/Declaration/Header/ProcessingInformation/ProcessingInstructions">
            <ProcessingInstructions>
              <xsl:value-of select="."/>
            </ProcessingInstructions>
          </xsl:for-each>
        </ProcessingInformation>
        <xsl:for-each select="/Declaration/Header/Seal">
          <Seal>
            <SealID>
              <xsl:value-of select="SealID"/>
            </SealID>
            <SealLanguage>
              <xsl:value-of select="SealLanguage"/>
            </SealLanguage>
          </Seal>
        </xsl:for-each>
          <xsl:choose>
          <xsl:when test='/Declaration/Header/DeclarantsReference = ""'>
            <DeclarantsReference>
              <xsl:text disable-output-escaping="no">A</xsl:text>
            </DeclarantsReference>
          </xsl:when>
          <xsl:otherwise>
            <DeclarantsReference>
              <xsl:value-of select="/Declaration/Header/DeclarantsReference"/>
            </DeclarantsReference>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:for-each select="/Declaration/Header/Items">
          <Items>
            <CustomsStatusOfGoods>
              <CPC>
                <xsl:value-of select="CustomsStatusOfGoods/CPC"/>
              </CPC>
              <CommodityCode>
                <xsl:value-of select="CustomsStatusOfGoods/CommodityCode"/>
              </CommodityCode>
              <ECSuplementaryMeasureCode1>
                <xsl:value-of select="CustomsStatusOfGoods/ECSuplementaryMeasureCode1"/>
              </ECSuplementaryMeasureCode1>
              <ECSuplementaryMeasureCode2>
                <xsl:value-of select="CustomsStatusOfGoods/ECSuplementaryMeasureCode2"/>
              </ECSuplementaryMeasureCode2>
              <PreferenceCode>
                <xsl:value-of select="CustomsStatusOfGoods/PreferenceCode"/>
              </PreferenceCode>
            </CustomsStatusOfGoods>
            <xsl:for-each select="ItemAI">
              <ItemAI>
                <AICode>
                  <xsl:value-of select="AICode"/>
                </AICode>
                <AIStatement>
                  <xsl:value-of select="AIStatement"/>
                </AIStatement>
                <AILanguage>
                  <xsl:value-of select="AILanguage"/>
                </AILanguage>
              </ItemAI>
            </xsl:for-each>
            <Locations>
              <CountryOfOriginCode>
                <xsl:value-of select="Locations/CountryOfOriginCode"/>
              </CountryOfOriginCode>
              <xsl:for-each select="Locations/ItemCountryonRouteCode">
                <ItemCountryonRouteCode>
                  <xsl:value-of select="."/>
                </ItemCountryonRouteCode>
              </xsl:for-each>
              <ItemDispatchCountry>
                <xsl:value-of select="Locations/ItemDispatchCountry"/>
              </ItemDispatchCountry>
              <ItemDestinationCountry>
                <xsl:value-of select="Locations/ItemDestinationCountry"/>
              </ItemDestinationCountry>
            </Locations>
            <Measurements>
              <GrossMass>
                <xsl:value-of select="Measurements/GrossMass"/>
              </GrossMass>
              <NetMass>
                <xsl:value-of select="Measurements/NetMass"/>
              </NetMass>
              <SupplementaryUnits>
                <xsl:value-of select="Measurements/SupplementaryUnits"/>
              </SupplementaryUnits>
              <ThirdQuantity>
                <xsl:value-of select="Measurements/ThirdQuantity"/>
              </ThirdQuantity>
            </Measurements>
            <xsl:for-each select="Package">
              <Package>
                <PackageNumber>
                  <xsl:value-of select="PackageNumber"/>
                </PackageNumber>
                <PackageKind>
                  <xsl:value-of select="PackageKind"/>
                </PackageKind>
                <PackageMarks>
                  <xsl:value-of select="PackageMarks"/>
                </PackageMarks>
                <PackageLanguage>
                  <xsl:value-of select="PackageLanguage"/>
                </PackageLanguage>
              </Package>
            </xsl:for-each>
            <PriceValue>
              <ItemStatisticalValue>
                <xsl:value-of select="PriceValue/ItemStatisticalValue"/>
              </ItemStatisticalValue>
              <ItemPrice>
                <xsl:value-of select="PriceValue/ItemPrice"/>
              </ItemPrice>
            </PriceValue>
            <ItemReferences>
              <xsl:for-each select="ItemReferences/ContainerID">
                <ContainerID>
                  <xsl:value-of select="."/>
                </ContainerID>
              </xsl:for-each>
              <QuotaNo>
                <xsl:value-of select="ItemReferences/QuotaNo"/>
              </QuotaNo>
              <UNDangerousGoodsCode>
                <xsl:value-of select="ItemReferences/UNDangerousGoodsCode"/>
              </UNDangerousGoodsCode>
            </ItemReferences>
            <GoodsDescription>
              <GoodsDescription>
                <xsl:value-of select="GoodsDescription/GoodsDescription"/>
              </GoodsDescription>
              <GoodsDescriptionLanguage>
                <xsl:value-of select="GoodsDescription/GoodsDescriptionLanguage"/>
              </GoodsDescriptionLanguage>
            </GoodsDescription>
            <Documents>
              <xsl:for-each select="Documents/PreviousDocument">
                <PreviousDocument>
                  <PreviousDocumentKind>
                    <xsl:value-of select="PreviousDocumentKind"/>
                  </PreviousDocumentKind>
                  <PreviousDocumentIdentifier>
                    <xsl:value-of select="PreviousDocumentIdentifier"/>
                  </PreviousDocumentIdentifier>
                  <PreviousDocumentType>
                    <xsl:value-of select="PreviousDocumentType"/>
                  </PreviousDocumentType>
                  <PreviousDocumentLanguage>
                    <xsl:value-of select="PreviousDocumentLanguage"/>
                  </PreviousDocumentLanguage>
                </PreviousDocument>
              </xsl:for-each>
              <xsl:for-each select="Documents/ItemDocument">
                <ItemDocument>
                  <DocumentCode>
                    <xsl:value-of select="DocumentCode"/>
                  </DocumentCode>
                  <DocumentPart>
                    <xsl:value-of select="DocumentPart"/>
                  </DocumentPart>
                  <DocumentQuantity>
                    <xsl:value-of select="DocumentQuantity"/>
                  </DocumentQuantity>
                  <DocumentReason>
                    <xsl:value-of select="DocumentReason"/>
                  </DocumentReason>
                  <DocumentReference>
                    <xsl:value-of select="DocumentReference"/>
                  </DocumentReference>
                  <DocumentStatus>
                    <xsl:value-of select="DocumentStatus"/>
                  </DocumentStatus>
                  <DocumentLanguage>
                    <xsl:value-of select="DocumentLanguage"/>
                  </DocumentLanguage>
                </ItemDocument>
              </xsl:for-each>
            </Documents>
            <Valuation>
              <ValuationMethodCode>
                <xsl:value-of select="Valuation/ValuationMethodCode"/>
              </ValuationMethodCode>
              <ItemValuationAdjustmentCode>
                <xsl:value-of select="Valuation/ItemValuationAdjustmentCode"/>
              </ItemValuationAdjustmentCode>
              <ItemValuationAdjustmentPercentage>
                <xsl:value-of select="Valuation/ItemValuationAdjustmentPercentage"/>
              </ItemValuationAdjustmentPercentage>
            </Valuation>
            <ItemTransportChargeMOP>
              <xsl:value-of select="ItemTransportChargeMOP"/>
            </ItemTransportChargeMOP>
            <xsl:for-each select="ItemProcessingInstructions">
              <ItemProcessingInstructions>
                <xsl:value-of select="."/>
              </ItemProcessingInstructions>
            </xsl:for-each>
          </Items>
        </xsl:for-each>
        <NumberOfPackages>
          <xsl:value-of select="/Declaration/Header/NumberOfPackages"/>
        </NumberOfPackages>
      </Header>
    </Declaration>
  </xsl:template>
</xsl:stylesheet>

所以对于源xml

<Declaration>
    <Message>
        <Meduim>#+#</Meduim>
        <MessageIdentifier>AA</MessageIdentifier>
        <CommonAccessReference></CommonAccessReference>
    </Message>
    <BeginingOfMessage>
        <MessageCode>ISD</MessageCode>
        <DeclarationCurrency></DeclarationCurrency>
        <MessageFunction>5</MessageFunction>
    </BeginingOfMessage>
</Declaration>

最终输出是

<Declaration>
    <Message>
        <Meduim></Meduim>
        <MessageIdentifier>AA</MessageIdentifier>
    </Message>
    <BeginingOfMessage>
        <MessageCode>ISD</MessageCode>
        <MessageFunction>5</MessageFunction>
    </BeginingOfMessage>
</Declaration>

This is in continuation of my question:

Merge functionality of two xsl files into a single file (not a xsl import or include issue)


I have to merge the solution (xsl) of above question to below xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">

 <xsl:template match="/">
    <Declaration>
      <Message>
        <Meduim>
          <xsl:value-of select="/Declaration/Message/Meduim"/>
        </Meduim>
        <MessageIdentifier>
          <xsl:value-of select="/Declaration/Message/MessageIdentifier"/>
        </MessageIdentifier>
        <ControlingAgencyCode>
          <xsl:value-of select="/Declaration/Message/ControlingAgencyCode"/>
        </ControlingAgencyCode>
        <AssociationAssignedCode>
          <xsl:value-of select="/Declaration/Message/AssociationAssignedCode"/>
        </AssociationAssignedCode>
        <CommonAccessReference>
          <xsl:value-of select="/Declaration/Message/CommonAccessReference"/>
        </CommonAccessReference>
      </Message>
      <BeginingOfMessage>
        <MessageCode>
          <xsl:value-of select="/Declaration/BeginingOfMessage/MessageCode"/>
        </MessageCode>
        <DeclarationCurrency>
          <xsl:value-of select="/Declaration/BeginingOfMessage/DeclarationCurrency"/>
        </DeclarationCurrency>
        <MessageFunction>
          <xsl:value-of select="/Declaration/BeginingOfMessage/MessageFunction"/>
        </MessageFunction>
      </BeginingOfMessage>
      <Header>
        <ProcessingInformation>
          <xsl:for-each select="/Declaration/Header/ProcessingInformation/ProcessingInstructions">
            <ProcessingInstructions>
              <xsl:value-of select="."/>
            </ProcessingInstructions>
          </xsl:for-each>
        </ProcessingInformation>
        <xsl:for-each select="/Declaration/Header/Seal">
          <Seal>
            <SealID>
              <xsl:value-of select="SealID"/>
            </SealID>
            <SealLanguage>
              <xsl:value-of select="SealLanguage"/>
            </SealLanguage>
          </Seal>
        </xsl:for-each>
          <xsl:choose>
          <xsl:when test='/Declaration/Header/DeclarantsReference = ""'>
            <DeclarantsReference>
              <xsl:text disable-output-escaping="no">A</xsl:text>
            </DeclarantsReference>
          </xsl:when>
          <xsl:otherwise>
            <DeclarantsReference>
              <xsl:value-of select="/Declaration/Header/DeclarantsReference"/>
            </DeclarantsReference>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:for-each select="/Declaration/Header/Items">
          <Items>
            <CustomsStatusOfGoods>
              <CPC>
                <xsl:value-of select="CustomsStatusOfGoods/CPC"/>
              </CPC>
              <CommodityCode>
                <xsl:value-of select="CustomsStatusOfGoods/CommodityCode"/>
              </CommodityCode>
              <ECSuplementaryMeasureCode1>
                <xsl:value-of select="CustomsStatusOfGoods/ECSuplementaryMeasureCode1"/>
              </ECSuplementaryMeasureCode1>
              <ECSuplementaryMeasureCode2>
                <xsl:value-of select="CustomsStatusOfGoods/ECSuplementaryMeasureCode2"/>
              </ECSuplementaryMeasureCode2>
              <PreferenceCode>
                <xsl:value-of select="CustomsStatusOfGoods/PreferenceCode"/>
              </PreferenceCode>
            </CustomsStatusOfGoods>
            <xsl:for-each select="ItemAI">
              <ItemAI>
                <AICode>
                  <xsl:value-of select="AICode"/>
                </AICode>
                <AIStatement>
                  <xsl:value-of select="AIStatement"/>
                </AIStatement>
                <AILanguage>
                  <xsl:value-of select="AILanguage"/>
                </AILanguage>
              </ItemAI>
            </xsl:for-each>
            <Locations>
              <CountryOfOriginCode>
                <xsl:value-of select="Locations/CountryOfOriginCode"/>
              </CountryOfOriginCode>
              <xsl:for-each select="Locations/ItemCountryonRouteCode">
                <ItemCountryonRouteCode>
                  <xsl:value-of select="."/>
                </ItemCountryonRouteCode>
              </xsl:for-each>
              <ItemDispatchCountry>
                <xsl:value-of select="Locations/ItemDispatchCountry"/>
              </ItemDispatchCountry>
              <ItemDestinationCountry>
                <xsl:value-of select="Locations/ItemDestinationCountry"/>
              </ItemDestinationCountry>
            </Locations>
            <Measurements>
              <GrossMass>
                <xsl:value-of select="Measurements/GrossMass"/>
              </GrossMass>
              <NetMass>
                <xsl:value-of select="Measurements/NetMass"/>
              </NetMass>
              <SupplementaryUnits>
                <xsl:value-of select="Measurements/SupplementaryUnits"/>
              </SupplementaryUnits>
              <ThirdQuantity>
                <xsl:value-of select="Measurements/ThirdQuantity"/>
              </ThirdQuantity>
            </Measurements>
            <xsl:for-each select="Package">
              <Package>
                <PackageNumber>
                  <xsl:value-of select="PackageNumber"/>
                </PackageNumber>
                <PackageKind>
                  <xsl:value-of select="PackageKind"/>
                </PackageKind>
                <PackageMarks>
                  <xsl:value-of select="PackageMarks"/>
                </PackageMarks>
                <PackageLanguage>
                  <xsl:value-of select="PackageLanguage"/>
                </PackageLanguage>
              </Package>
            </xsl:for-each>
            <PriceValue>
              <ItemStatisticalValue>
                <xsl:value-of select="PriceValue/ItemStatisticalValue"/>
              </ItemStatisticalValue>
              <ItemPrice>
                <xsl:value-of select="PriceValue/ItemPrice"/>
              </ItemPrice>
            </PriceValue>
            <ItemReferences>
              <xsl:for-each select="ItemReferences/ContainerID">
                <ContainerID>
                  <xsl:value-of select="."/>
                </ContainerID>
              </xsl:for-each>
              <QuotaNo>
                <xsl:value-of select="ItemReferences/QuotaNo"/>
              </QuotaNo>
              <UNDangerousGoodsCode>
                <xsl:value-of select="ItemReferences/UNDangerousGoodsCode"/>
              </UNDangerousGoodsCode>
            </ItemReferences>
            <GoodsDescription>
              <GoodsDescription>
                <xsl:value-of select="GoodsDescription/GoodsDescription"/>
              </GoodsDescription>
              <GoodsDescriptionLanguage>
                <xsl:value-of select="GoodsDescription/GoodsDescriptionLanguage"/>
              </GoodsDescriptionLanguage>
            </GoodsDescription>
            <Documents>
              <xsl:for-each select="Documents/PreviousDocument">
                <PreviousDocument>
                  <PreviousDocumentKind>
                    <xsl:value-of select="PreviousDocumentKind"/>
                  </PreviousDocumentKind>
                  <PreviousDocumentIdentifier>
                    <xsl:value-of select="PreviousDocumentIdentifier"/>
                  </PreviousDocumentIdentifier>
                  <PreviousDocumentType>
                    <xsl:value-of select="PreviousDocumentType"/>
                  </PreviousDocumentType>
                  <PreviousDocumentLanguage>
                    <xsl:value-of select="PreviousDocumentLanguage"/>
                  </PreviousDocumentLanguage>
                </PreviousDocument>
              </xsl:for-each>
              <xsl:for-each select="Documents/ItemDocument">
                <ItemDocument>
                  <DocumentCode>
                    <xsl:value-of select="DocumentCode"/>
                  </DocumentCode>
                  <DocumentPart>
                    <xsl:value-of select="DocumentPart"/>
                  </DocumentPart>
                  <DocumentQuantity>
                    <xsl:value-of select="DocumentQuantity"/>
                  </DocumentQuantity>
                  <DocumentReason>
                    <xsl:value-of select="DocumentReason"/>
                  </DocumentReason>
                  <DocumentReference>
                    <xsl:value-of select="DocumentReference"/>
                  </DocumentReference>
                  <DocumentStatus>
                    <xsl:value-of select="DocumentStatus"/>
                  </DocumentStatus>
                  <DocumentLanguage>
                    <xsl:value-of select="DocumentLanguage"/>
                  </DocumentLanguage>
                </ItemDocument>
              </xsl:for-each>
            </Documents>
            <Valuation>
              <ValuationMethodCode>
                <xsl:value-of select="Valuation/ValuationMethodCode"/>
              </ValuationMethodCode>
              <ItemValuationAdjustmentCode>
                <xsl:value-of select="Valuation/ItemValuationAdjustmentCode"/>
              </ItemValuationAdjustmentCode>
              <ItemValuationAdjustmentPercentage>
                <xsl:value-of select="Valuation/ItemValuationAdjustmentPercentage"/>
              </ItemValuationAdjustmentPercentage>
            </Valuation>
            <ItemTransportChargeMOP>
              <xsl:value-of select="ItemTransportChargeMOP"/>
            </ItemTransportChargeMOP>
            <xsl:for-each select="ItemProcessingInstructions">
              <ItemProcessingInstructions>
                <xsl:value-of select="."/>
              </ItemProcessingInstructions>
            </xsl:for-each>
          </Items>
        </xsl:for-each>
        <NumberOfPackages>
          <xsl:value-of select="/Declaration/Header/NumberOfPackages"/>
        </NumberOfPackages>
      </Header>
    </Declaration>
  </xsl:template>
</xsl:stylesheet>

so for source xml

<Declaration>
    <Message>
        <Meduim>#+#</Meduim>
        <MessageIdentifier>AA</MessageIdentifier>
        <CommonAccessReference></CommonAccessReference>
    </Message>
    <BeginingOfMessage>
        <MessageCode>ISD</MessageCode>
        <DeclarationCurrency></DeclarationCurrency>
        <MessageFunction>5</MessageFunction>
    </BeginingOfMessage>
</Declaration>

the final output is

<Declaration>
    <Message>
        <Meduim></Meduim>
        <MessageIdentifier>AA</MessageIdentifier>
    </Message>
    <BeginingOfMessage>
        <MessageCode>ISD</MessageCode>
        <MessageFunction>5</MessageFunction>
    </BeginingOfMessage>
</Declaration>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暗恋未遂 2024-10-18 08:56:52

我。执行一系列转换在 XSLT 应用程序中经常使用,尽管完全在 XSLT 1.0 中执行此操作需要使用特定于供应商的 xxx:node-set() 函数。在 XSLT 2.0 中,不需要这样的扩展,因为臭名昭著的 RTF 数据类型已被消除。

这是一个示例(太简单了,没有意义,但完整地说明了这是如何完成的):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
   <xsl:variable name="vrtfPass1">
    <xsl:apply-templates select="/*/*"/>
   </xsl:variable>

   <xsl:variable name="vPass1"
        select="ext:node-set($vrtfPass1)"/>

   <xsl:apply-templates mode="pass2"
        select="$vPass1/*"/>
 </xsl:template>

 <xsl:template match="num[. mod 2 = 1]">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <xsl:copy>
    <xsl:value-of select=". *2"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

想要的,产生正确的结果

<num>2</num>
<num>6</num>
<num>10</num>
<num>14</num>
<num>18</num>

解释

  1. 在第一步中,XML文档被转换,结果被定义为变量的值$vrtfPass1。这仅复制具有奇数(非偶数)值的 num 元素。

  2. $vrtfPass1 变量的类型为 RTF,不能直接用于 XPath 表达式,因此我们使用 EXSLT(由大多数人实现)将其转换为普通树XSLT 1.0 处理器)函数 ext:node-set 并定义另一个变量 -- $vPass1,其值为此树。

  3. 我们现在执行转换链中的第二个转换 - 根据第一个转换的结果,将其保留为变量 $vPass1 的值。为了不弄乱第一遍模板,我们指定新处理应该处于命名模式,称为“pass2”。在此模式下,任何 num 元素的值都会乘以 2。

另请参阅 Michael Kay 对第一个问题的回答,其中也解释了这种一般技术。

II。 XSLT 2.0 解决方案(无 RTF):

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:variable name="vPass1" >
   <xsl:apply-templates select="/*/*"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass2"
        select="$vPass1/*"/>
 </xsl:template>

 <xsl:template match="num[. mod 2 = 1]">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <xsl:copy>
    <xsl:value-of select=". *2"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

III。使用 FXSL 的 compose()compose-flist() 函数/模板

FXSL 库提供了两个方便的函数/模板,支持轻松的转换链接。前者由两个函数/转换组成,而后者由序列中提供的所有函数/转换组成。

这是一个简单、完整的代码示例

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myFun1="f:myFun1"
xmlns:myFun2="f:myFun2" 
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="xsl f ext myFun1 myFun2"
>
  <xsl:import href="compose.xsl"/>
  <xsl:import href="compose-flist.xsl"/>

  <!-- to be applied on any xml source -->

  <xsl:output method="text"/>
  <myFun1:myFun1/>
  <myFun2:myFun2/>


  <xsl:template match="/">

    <xsl:variable name="vFun1" select="document('')/*/myFun1:*[1]"/>
    <xsl:variable name="vFun2" select="document('')/*/myFun2:*[1]"/>
    Compose:
    (*3).(*2) 3 = 
    <xsl:call-template name="compose">
      <xsl:with-param name="pFun1" select="$vFun1"/>
      <xsl:with-param name="pFun2" select="$vFun2"/>
      <xsl:with-param name="pArg1" select="3"/>
    </xsl:call-template>

    <xsl:variable name="vrtfParam">
      <xsl:copy-of select="$vFun1"/>
      <xsl:copy-of select="$vFun2"/>
      <xsl:copy-of select="$vFun1"/>
    </xsl:variable>

    Multi Compose:
    (*3).(*2).(*3) 2 = 
    <xsl:call-template name="compose-flist">
      <xsl:with-param name="pFunList" select="ext:node-set($vrtfParam)/*"/>
      <xsl:with-param name="pArg1" select="2"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="myFun1:*" mode="f:FXSL">
    <xsl:param name="pArg1"/>

    <xsl:value-of select="3 * $pArg1"/>
  </xsl:template>

  <xsl:template match="myFun2:*" mode="f:FXSL">
    <xsl:param name="pArg1"/>

    <xsl:value-of select="2 * $pArg1"/>
  </xsl:template>
</xsl:stylesheet>

当此转换应用于任何 XML 文档(未使用)时,就会产生所需的正确结果

Compose:
(*3).(*2) 3 = 
18

Multi Compose:
(*3).(*2).(*3) 2 = 
36

I. Performing a chain of transformations is used quite often in XSLT applications, though doing this entirely in XSLT 1.0 requires the use of the vendor-specific xxx:node-set() function. In XSLT 2.0 no such extension is needed as the infamous RTF datatype is eliminated there.

Here is an example (too-simple to be meaningful, but illustrating completely how this is done):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
   <xsl:variable name="vrtfPass1">
    <xsl:apply-templates select="/*/*"/>
   </xsl:variable>

   <xsl:variable name="vPass1"
        select="ext:node-set($vrtfPass1)"/>

   <xsl:apply-templates mode="pass2"
        select="$vPass1/*"/>
 </xsl:template>

 <xsl:template match="num[. mod 2 = 1]">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <xsl:copy>
    <xsl:value-of select=". *2"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the following XML document:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

the wanted, correct result is produced:

<num>2</num>
<num>6</num>
<num>10</num>
<num>14</num>
<num>18</num>

Explanation:

  1. In the first step the XML document is transformed and the result is defined as the value of the variable $vrtfPass1. This copies only the num elements that have odd value (not even).

  2. The $vrtfPass1 variable, being of type RTF, is not directly usable for XPath expressions so we convert it to a normal tree, using the EXSLT (implemented by most XSLT 1.0 processors) function ext:node-set and defining another variable -- $vPass1 whose value is this tree.

  3. We now perform the second transformation in our chain of transformations -- on the result of the first transformation, that is kept as the value of the variable $vPass1. Not to mess with the first-pass template, we specify that the new processing should be in a named mode, called "pass2". In this mode the value of any num element is multiplied by two.

See also the answer of Michael Kay to your first question, which also explained this general technique.

II. XSLT 2.0 solution (no RTFs):

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:variable name="vPass1" >
   <xsl:apply-templates select="/*/*"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass2"
        select="$vPass1/*"/>
 </xsl:template>

 <xsl:template match="num[. mod 2 = 1]">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <xsl:copy>
    <xsl:value-of select=". *2"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

III. Using the compose() and compose-flist() functions/templates of FXSL

The FXSL library provides two convenient functions/template that support easy chaining of transformations. The former composes two functions/transformations while the latter composes all functions/transformations that are provided in a sequence.

Here is a simple, complete code example:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:myFun1="f:myFun1"
xmlns:myFun2="f:myFun2" 
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="xsl f ext myFun1 myFun2"
>
  <xsl:import href="compose.xsl"/>
  <xsl:import href="compose-flist.xsl"/>

  <!-- to be applied on any xml source -->

  <xsl:output method="text"/>
  <myFun1:myFun1/>
  <myFun2:myFun2/>


  <xsl:template match="/">

    <xsl:variable name="vFun1" select="document('')/*/myFun1:*[1]"/>
    <xsl:variable name="vFun2" select="document('')/*/myFun2:*[1]"/>
    Compose:
    (*3).(*2) 3 = 
    <xsl:call-template name="compose">
      <xsl:with-param name="pFun1" select="$vFun1"/>
      <xsl:with-param name="pFun2" select="$vFun2"/>
      <xsl:with-param name="pArg1" select="3"/>
    </xsl:call-template>

    <xsl:variable name="vrtfParam">
      <xsl:copy-of select="$vFun1"/>
      <xsl:copy-of select="$vFun2"/>
      <xsl:copy-of select="$vFun1"/>
    </xsl:variable>

    Multi Compose:
    (*3).(*2).(*3) 2 = 
    <xsl:call-template name="compose-flist">
      <xsl:with-param name="pFunList" select="ext:node-set($vrtfParam)/*"/>
      <xsl:with-param name="pArg1" select="2"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="myFun1:*" mode="f:FXSL">
    <xsl:param name="pArg1"/>

    <xsl:value-of select="3 * $pArg1"/>
  </xsl:template>

  <xsl:template match="myFun2:*" mode="f:FXSL">
    <xsl:param name="pArg1"/>

    <xsl:value-of select="2 * $pArg1"/>
  </xsl:template>
</xsl:stylesheet>

When this transformation is applied on any XML document (not used), the wanted, correct results are produced:

Compose:
(*3).(*2) 3 = 
18

Multi Compose:
(*3).(*2).(*3) 2 = 
36
帅冕 2024-10-18 08:56:52

Pure XSLT 1.0 不支持链接模板(也不支持整个样式表)。您可以通过调用第二个 xslt 模板并向其手动传递第一个 xslt 模板的输出来在 XSLT 之外解决此程序,也可以使用相当普遍的扩展函数 node-set()。 MSXML、.NET、EXSL 和许多其他实现都支持这样的功能。 node-set 的命名空间前缀根据 XSLT 实现的不同而有所不同,但 EXSL 前缀是一个不错的选择(.NET 虽然没有文档记录,但支持这一点)。

要使用 node-set 将模板的结果存储在 xsl:variablexsl:param 中,并执行类似 的操作。 xsl:apply-templates select="exsl:node-set($myvarname)"/>

最后,您当然可以重写两个模板以一次性提供两者的功能 - 但一般来说,这不是一件小事。

Pure XSLT 1.0 does not support chaining templates (nor stylesheets as a whole). You can either solve this program outside of XSLT by calling the second xslt template and passing it the output of the first manually, or you can use the fairly pervasive extension function node-set(). MSXML, .NET, EXSL and many other implementations support such a function. The namespace prefix for node-set varies depending on XSLT implementation, but the EXSL prefix is a good bet (and .NET, though undocumented, supports this).

To use node-set store the result of a template in an xsl:variable or xsl:param and do something like <xsl:apply-templates select="exsl:node-set($myvarname)"/>.

Finally, you can of course rewrite your two templates to provide the functionality of both in one pass - but in general, this isn't a trivial thing to do.

轮廓§ 2024-10-18 08:56:52

我不明白这个问题。
我在你上一个问题中发布的解决方案已经有效。

对于此输入:

<?xml version="1.0" encoding="UTF-8"?>
<Declaration>
    <Message>
        <Meduim>#+#</Meduim>
        <MessageIdentifier>AA</MessageIdentifier>
        <CommonAccessReference></CommonAccessReference>
    </Message>
    <BeginingOfMessage>
        <MessageCode>ISD</MessageCode>
        <DeclarationCurrency></DeclarationCurrency>
        <MessageFunction>5</MessageFunction>
    </BeginingOfMessage>
</Declaration>

输出将是:

<?xml version="1.0" encoding="UTF-8"?>
<Declaration>
    <Message>
        <Meduim/>
        <MessageIdentifier>AA</MessageIdentifier>
    </Message>
    <BeginingOfMessage>
        <MessageCode>ISD</MessageCode>
        <MessageFunction>5</MessageFunction>
    </BeginingOfMessage>
</Declaration>

事实上,您不需要原始样式表,因为基本上您只需复制树。

I don't understand the problem.
The solution I posted in your last question already works.

For this input:

<?xml version="1.0" encoding="UTF-8"?>
<Declaration>
    <Message>
        <Meduim>#+#</Meduim>
        <MessageIdentifier>AA</MessageIdentifier>
        <CommonAccessReference></CommonAccessReference>
    </Message>
    <BeginingOfMessage>
        <MessageCode>ISD</MessageCode>
        <DeclarationCurrency></DeclarationCurrency>
        <MessageFunction>5</MessageFunction>
    </BeginingOfMessage>
</Declaration>

Output will be:

<?xml version="1.0" encoding="UTF-8"?>
<Declaration>
    <Message>
        <Meduim/>
        <MessageIdentifier>AA</MessageIdentifier>
    </Message>
    <BeginingOfMessage>
        <MessageCode>ISD</MessageCode>
        <MessageFunction>5</MessageFunction>
    </BeginingOfMessage>
</Declaration>

You, in fact, don't need your original stylesheet, because basically you just copy the tree.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文