如何在XSLT中使用'xsl:apply-templates'获得XML属性值

时间:2018-10-03 20:04:04

标签: xml xslt apply-templates

我具有以下XML,并希望从code="MA"节点和<FullNameVerifiesToAddress>节点到节点<FullNameVerifiesToSSN>的XML属性<Summary>的值。

<PreciseIDServer>
    <Header>
        <ReportDate>09042018</ReportDate>
        <ReportTime>235641</ReportTime>
    </Header>
    <Summary>
        <TransactionID>1421957889</TransactionID>
        <InitialDecision>ACC</InitialDecision>
        <FinalDecision>ACC</FinalDecision>
        <CrossReferenceIndicatorsGrid>
            <FullNameVerifiesToAddress code="MA"/>
            <FullNameVerifiesToSSN code="MA"/>
        </CrossReferenceIndicatorsGrid>
    </Summary>
</PreciseIDServer>

我现在使用以下XSLT将<ReportTime>节点中的<Header>放入<summary>中,但是在Summary节点中我也需要上述属性。

<xsl:template match="Summary">
    <xsl:copy>
        <xsl:apply-templates select="@* | ancestor::PreciseIDServer/Header/ReportTime | node()"/>
    </xsl:copy>
</xsl:template>

我想要作为输出的XML应该是

<PreciseIDServer>
    <Header>
        <ReportDate>09042018</ReportDate>
        <ReportTime>235641</ReportTime>
    </Header>
    <Summary>
        <TransactionID>1421957889</TransactionID>
        <InitialDecision>ACC</InitialDecision>
        <FinalDecision>ACC</FinalDecision>
        <ReportTime>235641</ReportTime>
        <FullNameVerifiesToAddress>MA </FullNameVerifiesToAddress>
        <FullNameVerifiesToSSN> MA </FullNameVerifiesToSSN>
        <CrossReferenceIndicatorsGrid>
            <FullNameVerifiesToAddress code="MA"/>
            <FullNameVerifiesToSSN code="MA"/>
        </CrossReferenceIndicatorsGrid>
    </Summary>
</PreciseIDServer>

1 个答案:

答案 0 :(得分:0)

我认为您需要将某些节点推入第二种模式,因为要在未复制时将其输出,同时还希望对其进行转换,因此将使用最小的XSLT 3解决方案

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

    <xsl:template match="Summary">
        <xsl:copy>
            <xsl:apply-templates select="@* | ancestor::PreciseIDServer/Header/ReportTime | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="CrossReferenceIndicatorsGrid">
        <xsl:apply-templates mode="code-att-to-content"/>
        <xsl:next-match/>
    </xsl:template>

    <xsl:template match="CrossReferenceIndicatorsGrid/*" mode="code-att-to-content">
        <xsl:copy>{@code}</xsl:copy>
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bdxtqL

对于XSLT 2,您需要替换the xsl:mode declaration with the identity transformation template

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

the text value template {@code}<xsl:value-of select="@code"/>

对于XSLT 1,您需要进行与XSLT 2相同的更改,但是还需要在身份模板上放置一个名称(即,将<xsl:template match="@* | node()">更改为<xsl:template match="@* | node()" name="identity">)并替换为{{1} }和<xsl:next-match/>