【问题标题】:XSLT 1.0 Remove Duplicates in Element ValueXSLT 1.0 删除元素值中的重复项
【发布时间】:2014-08-28 01:51:59
【问题描述】:

我有一个 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>

任何帮助将不胜感激。

【问题讨论】:

  • 关于您的 XSLT 代码最有趣的部分是在匹配 AIRPORTSFILE 的模板中存在 &lt;catalog&gt; 元素。
  • catalog 是我想要在输出 XML 中的根元素。您能帮我删除重复项吗?
  • 我想要目录。但这对不删除重复项的原因没有影响吗?
  • 是什么让您认为它们没有被删除?
  • @michael.hor257k 这是我为一份文件得到的结果: D1 2014-03-15 0615 2014-03-14 0930 A1 D2 2014 -03-14 0615 2014-03-15 0930 A2 D2 2014-03-15 0615 2014-03-15 0930 A2 ALC,ALC,PFO

标签: xml xslt duplicates xslt-1.0


【解决方案1】:

您当前的代码在我看来如此复杂和冗长,我认为最好从头开始。我的意思是从思考如何解决问题开始。

为了解决您的问题,您需要遵循这些步骤。 (或者说,这是一种解决方法)。

  • 编写一个匹配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>

【讨论】:

  • 您是否试图通过不提供最佳答案来惩罚 OP?有(并且将会有)其他人阅读这篇文章。
  • @michael.hor257k 我无意惩罚某人。编辑了我的答案,将样式表更改为使用键,而不是 following-sibling:: 轴。
  • 好的,那么。我认为没有人会回答这个问题,尤其是你们,但是...... FWIW,我投票结束了这个问题。
  • 谢谢@Mathias Müller。这似乎有效。我唯一看到的是第二个文档的arrivalAirport 是空的。如果您查看输入的 xml 文件。第二个文档中的两个值都是 P1。我假设需要对 for-each 进行一些修改。不过感谢您的帮助!
  • @Raj 我没有看到任何需要修改的地方。 (点击here自己查看)。在您的输入 XML 中,只有“P1”,在我的输出中也是如此。如果对您有帮助,请考虑接受这个问题(在左侧打勾)。
猜你喜欢
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 2019-08-10
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多