Как получить значения атрибута XML с помощью 'xsl: apply-templates' в XSLT - PullRequest
0 голосов
/ 03 октября 2018

У меня есть следующий XML, и я хотел бы получить значение атрибута XML code="MA" из узла <FullNameVerifiesToAddress> и узла <FullNameVerifiesToSSN> в узел <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-код, который я хочу получить как OUTPUT, должен выглядеть примерно так:

<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 голосов
/ 04 октября 2018

Я думаю, что вам нужно протолкнуть некоторые узлы через второй режим, так как вы хотите вывести их после того, как они не скопированы, а также хотите преобразовать их, поэтому минимальное решение 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 вам необходимо заменить объявление xsl:mode на шаблон преобразования идентификаторов

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

и шаблон текстового значения {@code} с <xsl:value-of select="@code"/>.

. Для XSLT 1 необходимо внести те же изменения, что и для XSLT 2, но дополнительно необходимо указать имя для идентификатора.шаблон (т.е. измените <xsl:template match="@* | node()"> на <xsl:template match="@* | node()" name="identity">) и замените использование <xsl:next-match/> на <xsl:call-template name="identity"/>.

...