【问题标题】:XSLT 1.0: How to move an attribute and its value to only the first element of a new elementXSLT 1.0:如何将属性及其值仅移动到新元素的第一个元素
【发布时间】:2021-09-14 16:25:22
【问题描述】:

我有以下 XML:

<?xml version="1.0" encoding="utf-8"?>
<DocumentElement>
  <Invoice>
    <Header Misc="5.00" TotalAmount="33.00" />
    <Packages>
      <Package>
        <Lines>
          <Line>
            <LineCharge Amount="28.00" />
          </Line>
        </Lines>
      </Package>
      <Package>
        <Lines>
          <Line>
            <LineCharge Amount="0.00" />
          </Line>
        </Lines>
      </Package>
    </Packages>
  </Invoice>
</DocumentElement>

并应用以下模板将 Misc 属性及其值从 Header 元素中移出,创建了一个名为 LineCharge 的新元素并将 Misc 的值分配给它。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"  xmlns:xe="urn:XSLTExtender"
                exclude-result-prefixes="msxsl">

<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />

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

  <xsl:template match="@Misc" />
  <xsl:template match ="LineCharge[1]" >
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
    <xsl:if test="normalize-space(//Invoice/Header/@Misc) != '' and number(//Invoice/Header/@Misc) = normalize-space(//Invoice/Header/@Misc)">
      <xsl:element name ="LineCharge">        
        <xsl:attribute name="Chargecd" >
          <xsl:value-of select="'CD01'"/>
        </xsl:attribute>
        <xsl:attribute name="Amount" >
          <xsl:value-of select="//Invoice/Header/@Misc"/>
        </xsl:attribute>
      </xsl:element>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

我得到以下输出:

<DocumentElement><Invoice>
  <Header TotalAmount="33.00" />
  <Packages>
    <Package>
      <Lines>
        <Line>
          <LineCharge Amount="28.00" />
          <LineCharge Chargecd="CD01" Amount="5.00" />
        </Line>
      </Lines>
    </Package>
    <Package>
      <Lines>
        <Line>
          <LineCharge Amount="0.00" />
          <LineCharge Chargecd="CD01" Amount="5.00" />
        </Line>
      </Lines>
    </Package>
  </Packages>
</Invoice></DocumentElement>

TotalAmount 应该是 33.00(即 28.00 + 5.00),但由于新 LineCharge 元素对每个 Package 元素重复,所以 Total 现在是 38.00,这是错误的。

如何获得以下输出,其中 Misc 值仅移动到第一个 Package 元素,而不是其兄弟元素:

<DocumentElement><Invoice>
  <Header TotalAmount="33.00" />
  <Packages>
    <Package>
      <Lines>
        <Line>
          <LineCharge Amount="28.00" />
          <LineCharge Chargecd="CD01" Amount="5.00" />
        </Line>
      </Lines>
    </Package>
    <Package>
      <Lines>
        <Line>
          <LineCharge Amount="0.00" />          
        </Line>
      </Lines>
    </Package>
  </Packages>
</Invoice></DocumentElement>

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    为什么不简单:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Package[1]/Lines/Line[1]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <LineCharge Chargecd="CD01" Amount="{ancestor::Invoice/Header/@Misc}" />
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="@Misc"/>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 谢谢你迈克尔!
    猜你喜欢
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多