我是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>
期望输出
<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>
<Invoice>
元素可以包含Id属性<Invoice Id="IR1564897">
如何查看以下内容。
<Refernce>DN1235588</Reference>
的值作为Id
<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>
以上内容未输出完整的<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>
如果其中任何一个始终存在,这是否可以在<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>
答案 0 :(得分:6)
答案最短:
<xsl:template match="Invoice[not(@Id)]">
<Invoice Id="{(../DeliveryNote/Reference|
../DeliveryNote/HoldingRef)[1]}">
<xsl:apply-templates select="@* | node()"/>
</Invoice>
</xsl:template>
答案 1 :(得分:0)
试一试:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="//Order"/>
</xsl:template>
<!-- Match invoices without ids -->
<!-- [DeliveryNote[Reference or HoldingRef] - defend against empty attributes -->
<xsl:template match="Invoice[not(@id)][DeliveryNote[Reference or HoldingRef]]">
<xsl:copy>
<!-- create an attribute and fetch required data. In case Reference is present then insert reference
otherwise - HoldingRef -->
<xsl:attribute name="Id">
<xsl:value-of select="following-sibling::DeliveryNote[1]/Reference |
following-sibling::DeliveryNote[1]/HoldingRef"/>
</xsl:attribute>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//DeliveryNote"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
关于你的问题:
以上不输出完整元素。我怎么能纠正这个?
见我的例子。
如果其中任何一个始终存在,这是否可以在
<Reference>
和<HoldingRef>
之间切换?
使用XPath(在我的示例中)或使用xsl:choose
。
答案 2 :(得分:0)
这个怎么样?
<xsl:template match="Invoice[not(@Id)]">
<xsl:element name="Invoice">
<xsl:attribute name="Id">
<xsl:variable name="REF" select="../DeliveryNote/Reference"/>
<xsl:choose>
<xsl:when test="not($REF)">
<xsl:value-of select="../DeliveryNote/HoldingRef"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../DeliveryNote/Reference"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
使用它代替<xsl:template match="Order/Documents/Invoice[not(@Id)]">