[英]XSLT 1.0 Remove Duplicates in Element Value
我有一个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-从变量中删除重复节点和XSLT 1.0-删除重复项字段以供参考,但无法使其正常工作。
以下是我在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>
任何帮助都感激不尽。
您当前的代码对我来说是如此复杂和漫长,以至于我认为最好从头开始。 我的意思是从思考如何解决问题开始。
这些是您需要解决的步骤。 (或者说,这是解决问题的一种方法)。
AIRPORTSFILE
匹配的模板,并代之输出一个catalog
元素。 将模板应用于内容。 document
匹配的模板并将其复制。 对于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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.