使用XSL基于XML参数添加节点

时间:2013-03-18 16:43:53

标签: xml xslt add

我的目标是在XML文件中添加一个新元素,如果其中一个当前子元素等于条件。如果不满足该条件,请继续使用原始XML文件的当前模板。

我有一个示例XML文件,目前下面包含2个订购商品。 XML文件的整体结构将保持不变,但订购的项目数量将是可变的,这可以添加额外的AlbumOrderItems,因为客户订单对于每个XML文件都是唯一的。

原始XML文件

<AlbumOrder> 
   <PartnerCode>ABC Company</PartnerCode> 
   <AffiliateCode>abcpro</AffiliateCode> 
   <PartnerOrderID>449</PartnerOrderID> 
   <NumItems>2</NumItems> 
   <DateTime>03/14/2013 12:16 AM</DateTime> 
<AlbumOrderItem> 
   <PartnerCode>ABC Company</PartnerCode>
   <AffiliateCode>abcpro</AffiliateCode> 
   <PartnerOrderID>449</PartnerOrderID> 
   <PartnerOrderItemID>1</PartnerOrderItemID> 
   <DateTime>03/14/2013 12:16 AM</DateTime> 
   <ProductCategory>ALBUM</ProductCategory> 
   <Quantity>2</Quantity> 
<ShipAddress> 
   <FirstName>Joe</FirstName> 
   <LastName>Black</LastName> 
</ShipAddress> 
</AlbumOrderItem>
<AlbumOrderItem> 
    <PartnerCode>ABC Company</PartnerCode> 
    <AffiliateCode>abcpro</AffiliateCode> 
    <PartnerOrderID>449</PartnerOrderID> 
    <PartnerOrderItemID>2</PartnerOrderItemID> 
    <DateTime>03/14/2013 12:16 AM</DateTime>  
    <ProductCategory>CARD</ProductCategory>  
    <Quantity>1</Quantity> 
    <Package>10</Package> 
    <NumPrints>10</NumPrints> 
<ShipAddress> 
    <FirstName>Joe</FirstName>
    <LastName>Black</LastName> 
</ShipAddress> 
</AlbumOrderItem> 
</AlbumOrder>

如果ProductCategory等于“ALBUM”,则向AlbumOrderItem添加一个新元素。下面的示例XML输出包含两个标题为的新添加元素: 包和NumPrints 这些都被添加到第一个AblumOrderItem

所需的输出XML

<AlbumOrder> 
   <PartnerCode>ABC Company</PartnerCode> 
   <AffiliateCode>abcpro</AffiliateCode> 
   <PartnerOrderID>449</PartnerOrderID> 
   <NumItems>2</NumItems> 
   <DateTime>03/14/2013 12:16 AM</DateTime> 
 <AlbumOrderItem> 
   <PartnerCode>ABC Company</PartnerCode>
   <AffiliateCode>abcpro</AffiliateCode> 
   <PartnerOrderID>449</PartnerOrderID> 
   <PartnerOrderItemID>1</PartnerOrderItemID> 
   <DateTime>03/14/2013 12:16 AM</DateTime> 
   <ProductCategory>ALBUM</ProductCategory> 
   <Quantity>2</Quantity> 
   <Package>XY</Package>      ****NODE to add
   <NumPrints>Z</NumPrints>   ****NODE to add
<ShipAddress> 
   <FirstName>Joe</FirstName> 
   <LastName>Black</LastName> 
</ShipAddress> 
</AlbumOrderItem>
<AlbumOrderItem> 
   <PartnerCode>ABC Company</PartnerCode> 
   <AffiliateCode>abcpro</AffiliateCode> 
   <PartnerOrderID>449</PartnerOrderID> 
   <PartnerOrderItemID>2</PartnerOrderItemID> 
   <DateTime>03/14/2013 12:16 AM</DateTime>  
   <ProductCategory>CARD</ProductCategory>  
   <Quantity>1</Quantity> 
   <Package>10</Package> 
   <NumPrints>10</NumPrints> 
<ShipAddress> 
   <FirstName>Joe</FirstName>
   <LastName>Black</LastName> 
</ShipAddress> 
</AlbumOrderItem> 
</AlbumOrder>

我目前正在使用下面的文件,但它似乎没有应用所需的更改。它似乎只是生成原始XML的完整副本 在默认的XSL模板/规则上。我不确定下面是否存在语法问题,尤其是模板匹配参数。我也不确定如何搜索或循环 通过整个XML文件中的所有ProductCategory元素。如果您有任何疑问,请告诉我。如果ProductCategory等于ALBUM并且考虑多个AlbumOrderItems部分,那么为了将节点添加到AlbumOrderItem,将非常感谢任何帮助。

当前的XSL脚本

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:param name="TESTname">PACK_TEST</xsl:param>
 <xsl:param name="TESTvalue"><xsl:value-of select="AlbumOrder/AlbumOrderItem/Package"/>
 </xsl:param>

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

 <xsl:template match="AlbumOrderItem[ProductCategory=Album]">
 <xsl:element name="{$TESTname}"><xsl:value-of select="$TESTvalue"/></xsl:element>
 <xsl:apply-templates select="node()|@*"/>
 </xsl:template>
 </xsl:stylesheet>  

2 个答案:

答案 0 :(得分:1)

缺少引号和错误案例见下文

<xsl:template match="AlbumOrderItem[ProductCategory='ALBUM']">

答案 1 :(得分:0)

Treemonkey已经证明了你在路径中遇到的错误。如果您对如何在您指定的特定位置(在ShipAddress之前)插入这些节点感兴趣,那么您可以这样做:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*" />
  <xsl:param name="TESTname">PACK_TEST</xsl:param>
  <xsl:param name="TESTvalue">
    <xsl:value-of select="AlbumOrder/AlbumOrderItem/Package"/>
  </xsl:param>

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

  <xsl:template match="AlbumOrderItem[ProductCategory = 'ALBUM']/ShipAddress">
    <xsl:element name="{$TESTname}">
      <xsl:value-of select="$TESTvalue" />
    </xsl:element>
    <xsl:call-template name="Copy" />
  </xsl:template>
</xsl:stylesheet>