XSLT 1.0删除元素值中的重复项

时间:2014-08-28 01:51:59

标签: xml xslt duplicates xslt-1.0

我有一个xml文件,我需要将元素的值组合到一个元素中,并确保没有重复项。下面是输入的xml文件。

           <AIRPORTSFILE>
           <document name="SAMPLE1">
                 <DEPARTURE_AIRPORT>D1</DEPARTURE_AIRPORT>
                 <DEPARTURE_DATE>2014-03-15</DEPARTURE_DATE>
                 <DEPARTURE_TIME>0615</DEPARTURE_TIME>
                 <ARRIVAL_DATE>2014-03-14</ARRIVAL_DATE>
                 <ARRIVAL_TIME>0930</ARRIVAL_TIME>
                 <ARRIVAL_AIRPORT>A1</ARRIVAL_AIRPORT>

                 <DEPARTURE_AIRPORT>D2</DEPARTURE_AIRPORT>
                 <DEPARTURE_DATE>2014-03-14</DEPARTURE_DATE>
                 <DEPARTURE_TIME>0615</DEPARTURE_TIME>
                 <ARRIVAL_DATE>2014-03-15</ARRIVAL_DATE>
                 <ARRIVAL_TIME>0930</ARRIVAL_TIME>
                 <ARRIVAL_AIRPORT>A2</ARRIVAL_AIRPORT>

                 <DEPARTURE_AIRPORT>D2</DEPARTURE_AIRPORT>
                 <DEPARTURE_DATE>2014-03-15</DEPARTURE_DATE>
                 <DEPARTURE_TIME>0615</DEPARTURE_TIME>
                 <ARRIVAL_DATE>2014-03-15</ARRIVAL_DATE>
                 <ARRIVAL_TIME>0930</ARRIVAL_TIME>
                 <ARRIVAL_AIRPORT>A2</ARRIVAL_AIRPORT>
          </document>


          <document name="SAMPLE2">
                 <DEPARTURE_AIRPORT>2014-06-05</DEPARTURE_AIRPORT>
                 <DEPARTURE_DATE>2014-06-05</DEPARTURE_DATE>
                 <DEPARTURE_TIME>1815</DEPARTURE_TIME>
                 <ARRIVAL_DATE>2014-06-05</ARRIVAL_DATE>
                 <ARRIVAL_TIME>2130</ARRIVAL_TIME>
                 <ARRIVAL_AIRPORT>P1</ARRIVAL_AIRPORT>

                 <DEPARTURE_AIRPORT>2014-06-06</DEPARTURE_AIRPORT>
                 <DEPARTURE_DATE>2014-06-06</DEPARTURE_DATE>
                 <DEPARTURE_TIME>1815</DEPARTURE_TIME>
                 <ARRIVAL_DATE>2014-06-05</ARRIVAL_DATE>
                 <ARRIVAL_TIME>2130</ARRIVAL_TIME>
                 <ARRIVAL_AIRPORT>P1</ARRIVAL_AIRPORT>
          </document>
          </AIRPORTSFILE>

输出必须是:

         <catalog>
         <document name="SAMPLE1">
                <departureDate>2014-03-15,2014-03-14</departureDate>
                <arrivalAirport>A1,A2</arrivalAirport>
         </document>
         <document name="SAMPLE2">
                <departureDate>2014-06-05,2014-06-06</departureDate>
                <arrivalAirport>P1</arrivalAirport>
         </document>
         </catalog>

我查看了XSLT 1.0 - Remove Duplicate Nodes From VariableXSLT 1.0 - Remove duplicates fields作为参考,但无法让它正常工作。

以下是我在xsl 1.0文件中的内容,以使DEPARTURE_DATE正常工作。

<xsl:key name="kDepartureDate" match="DEPARTURE_DATE" use="."/>


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

<xsl:template match="DEPARTURE_DATE[generate-id() = 
                           generate-id(key('kDepartureDate', .)[1])]"  name="depDateCopy">
    <xsl:call-template name="Copy" />
</xsl:template>

<xsl:template match="AIRPORTSFILE">
    <catalog>
        <xsl:for-each select="document">
        <xsl:variable name="departureDate">
                <xsl:call-template name="depDateCopy"></xsl:call-template>
        </xsl:variable>
        </xsl:for-each>
     </catalog>
</xsl:template>

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您当前的代码看起来如此复杂且对我来说很啰嗦,我觉得从头开始是最好的。我的意思是从思考如何解决问题开始。

这些是您需要遵循的步骤,以解决您的问题。 (或者,让我们说,这是解决它的一种方式)。

  • 编写与AIRPORTSFILE匹配的模板,并输出catalog元素。将模板应用于内容。
  • 编写与document匹配的模板并将其复制。

对于document:

的内容
  • 复制document
  • 的所有属性
  • 引入元素departureDate并查找具有不同值的所有元素DEPARTURE_DATE(使用键)。复制他们的文字内容。如果当前元素不是最后一个元素,则输出逗号。
  • 介绍元素arrivalAirport并重复上述内容。

这是一种以实际XSLT易于重现的方式编写的伪代码。

<强>样式表

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:strip-space elements="*"/>

    <xsl:key name="dep-date" match="DEPARTURE_DATE" use="."/>
    <xsl:key name="arr-air" match="ARRIVAL_AIRPORT" use="."/>

    <xsl:template match="AIRPORTSFILE">
      <catalog>
          <xsl:apply-templates/>
      </catalog>
    </xsl:template>

    <xsl:template match="document">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <departureDate>
                <xsl:for-each select="DEPARTURE_DATE[count(. | key('dep-date', .)[1]) = 1]">
                    <xsl:value-of select="."/>
                    <xsl:if test="position() != last()">
                        <xsl:text>,</xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </departureDate>
            <arrivalAirport>
                <xsl:for-each select="ARRIVAL_AIRPORT[count(. | key('arr-air', .)[1]) = 1]">
                    <xsl:value-of select="."/>
                    <xsl:if test="position() != last()">
                        <xsl:text>,</xsl:text>
                    </xsl:if>
                </xsl:for-each>
            </arrivalAirport> 
        </xsl:copy>
    </xsl:template>

</xsl:transform>

XML输出

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
   <document name="SAMPLE1">
      <departureDate>2014-03-15,2014-03-14</departureDate>
      <arrivalAirport>A1,A2</arrivalAirport>
   </document>
   <document name="SAMPLE2">
      <departureDate>2014-06-05,2014-06-06</departureDate>
      <arrivalAirport>P1</arrivalAirport>
   </document>
</catalog>