使用XSL重命名或合并重复的XML标记

时间:2013-11-04 06:39:41

标签: xml xslt

我有以下XML文件,每个SALES标记中都有重复的DateSold标记。 我需要将它们替换为DateSold和TimeSold。或者将日期和时间部分合并为单个标记。

源XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <SALES>
      <InvoiceID>A13A30000011</InvoiceID>
      <LineID>1</LineID>
      <UPC>058030020130</UPC>
      <Desc>PS WQ VIT E 200IU 100'S</Desc>
      <DateSold>2013-10-30</DateSold>
      <DateSold>10:02:42</DateSold>
      <QTY>000001</QTY>
      <UnitRetail>000006.99</UnitRetail>
      <UnitCost>000003.37</UnitCost>
   </SALES>
   <SALES>
      <InvoiceID>A13A30000021</InvoiceID>
      <LineID>2</LineID>
      <UPC>063601699165</UPC>
      <Desc>GENTEAL GEL DROPS 15ML</Desc>
      <DateSold>2013-10-30</DateSold>
      <DateSold>10:03:15</DateSold>
      <QTY>000001</QTY>
      <UnitRetail>000010.99</UnitRetail>
      <UnitCost>000007.44</UnitCost>
   </SALES>
</root>

输出将是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <SALES>
      <InvoiceID>A13A30000011</InvoiceID>
      <LineID>1</LineID>
      <UPC>058030020130</UPC>
      <Desc>PS WQ VIT E 200IU 100'S</Desc>
      <DateSold>2013-10-30</DateSold>
      <TimeSold>10:02:42</TimeSold>
      <QTY>000001</QTY>
      <UnitRetail>000006.99</UnitRetail>
      <UnitCost>000003.37</UnitCost>
   </SALES>
   <SALES>
      <InvoiceID>A13A30000021</InvoiceID>
      <LineID>2</LineID>
      <UPC>063601699165</UPC>
      <Desc>GENTEAL GEL DROPS 15ML</Desc>
      <DateSold>2013-10-30</DateSold>
      <TimeSold>10:03:15</TimeSold>
      <QTY>000001</QTY>
      <UnitRetail>000010.99</UnitRetail>
      <UnitCost>000007.44</UnitCost>
   </SALES>
</root>

如果将其合并为

,则可以
    <SALES>
    <InvoiceID>A13A30000021</InvoiceID>
    <LineID>2</LineID>
    <UPC>063601699165</UPC>
    <Desc>GENTEAL GEL DROPS 15ML</Desc>
    <DateSold>2013-10-30 10:03:15</TimeSold>
    <QTY>000001</QTY>
    <UnitRetail>000010.99</UnitRetail>
    <UnitCost>000007.44</UnitCost>      
</SALES>

2 个答案:

答案 0 :(得分:1)

我终于找到了解决方案。以下xslt将第二个Datesold标记替换为每个Sales标记中的TimeSold。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>
<xsl:template match="SALES/DateSold[2]">
    <TimeSold>
        <xsl:apply-templates select="@*|node()" />
    </TimeSold>
</xsl:template>
</xsl:stylesheet>

我得到了最终结果:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <SALES>
    <InvoiceID>A13A30000011</InvoiceID>
    <LineID>1</LineID>
    <UPC>058030020130</UPC>
    <Desc>PS WQ VIT E 200IU 100'S</Desc>
    <DateSold>2013-10-30</DateSold>
    <TimeSold>10:02:42</TimeSold>
    <QTY>000001</QTY>
    <UnitRetail>000006.99</UnitRetail>
    <UnitCost>000003.37</UnitCost>
  </SALES>
  <SALES>
    <InvoiceID>A13A30000021</InvoiceID>
    <LineID>2</LineID>
    <UPC>063601699165</UPC>
    <Desc>GENTEAL GEL DROPS 15ML</Desc>
    <DateSold>2013-10-30</DateSold>
    <TimeSold>10:03:15</TimeSold>
    <QTY>000001</QTY>
    <UnitRetail>000010.99</UnitRetail>
    <UnitCost>000007.44</UnitCost>
  </SALES>
</root>

答案 1 :(得分:0)

嗯,你没有展示你到目前为止所尝试的内容,所以我只会给出更一般的建议。

与往常一样,如果您想保持大部分结构不变,请从身份模板开始将所有输入复制到输出结构:

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

然后制作一些特殊模板,用于处理您要以不同方式处理的标记。 您的问题有很多可能的解决方案,其中一个是匹配DateSold元素,并将其写为DateSoldTimeSold,具体取决于它是第一个还是sales元素中的第二个子元素(如果它们总是以这种方式排序)。

另一种方法是匹配Sales元素,选择两个子元素并将它们以不同方式组合/写入输出文件,并通过apply-templates调用复制其他元素(然后调用您的身份模板再次)。

关于如何具体执行此操作,显示您在XSLT上尝试或阅读过的内容。网上有足够的资源。一个好的起点可能是www.w3schools.com

他们有每个xslt标记的示例。 apply-templates的{​​{3}}就是this