XSL转换 - 插入属性

use*_*850 1 xslt

我是xsl转换的初学者

我有一些xml,当该属性不存在时,我需要将一个属性插入元素.

以下面的xml为例.

<Order Id="IR1598756" Status="2">
  <Details>
    <SomeInfo>Sample Data</SomeInfo>
  </Details>
  <Documents>
    <Invoice>
      <Date>15-02-2011</Date>
      <Time>11:22</Time>
      <Employee Id="159">James Morrison</Employee>
    </Invoice>
    <DeliveryNote>
      <Reference>DN1235588</Reference>
      <HoldingRef>HR1598785</HoldingRef>
      <Date>16-02-2011</Date>
      <Time>15:00</Time>
      <Employee Id="25">Javi Cortez</Employee>
    </DeliveryNote>
  </Documents>
</Order>
Run Code Online (Sandbox Code Playgroud)

期望的输出

<Order Id="IR1598756" Status="2">
  <Details>
    <SomeInfo>Sample Data</SomeInfo>
  </Details>
  <Documents>
    <Invoice Id="DN1235588">
      <Date>15-02-2011</Date>
      <Time>11:22</Time>
      <Employee Id="159">James Morrison</Employee>
    </Invoice>
  </Documents>
</Order>    
Run Code Online (Sandbox Code Playgroud)

<Invoice>元素可以具有Id属性<Invoice Id="IR1564897">

我该如何检查以下内容.

  1. 检查该属性是否存在
  2. 如果没有,那么插入的值<Refernce>DN1235588</Reference>作为Id
  3. 如果没有<Reference>使用的价值<HoldingRef>HR1598785</HoldingRef>

我正在考虑实现类似以下内容

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

  <xsl:template match="/">
    <xsl:apply-templates select="//Order"/>
  </xsl:template>

  <xsl:template match="Order/Documents/Invoice[not(@Id)]">
      <xsl:attribute name="Id">
        <xsl:value-of select="//Documents/DeliveryNote/Reference"/>
      </xsl:attribute>      
  </xsl:template>
Run Code Online (Sandbox Code Playgroud)

以上不输出完整<Invoice>元素.我怎么能纠正这个?

  <xsl:if test="Order/Documents/DeliveryNote/Reference">
    <xsl:value-of select="//Documents/DeliveryNote/Reference"/>
  </xsl:if>
  <xsl:if test="Not(Order/Documents/DeliveryNote/Reference)">
    <xsl:value-of select="//Documents/DeliveryNote/HoldingRef"/>
  </xsl:if>
Run Code Online (Sandbox Code Playgroud)

如果任何一个将永远存在将这工作交替<Reference><HoldingRef>

在Alex的帮助下:以下对我来说取代了属性

  <xsl:template match="Order/Documents/Invoice[not(@Id)]">       
    <Invoice>
      <xsl:attribute name="Id">         
        <xsl:value-of Select="//Documents/DeliveryNote/Reference"/>
      </xsl:attribute>         
      <xsl:apply-templates select="@* | node()"/>
    </Invoice>
  </xsl:template>
Run Code Online (Sandbox Code Playgroud)

小智 6

最短的答案:

<xsl:template match="Invoice[not(@Id)]">
    <Invoice Id="{(../DeliveryNote/Reference|
                   ../DeliveryNote/HoldingRef)[1]}">
        <xsl:apply-templates select="@* | node()"/>
    </Invoice>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)