我有一个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 Variable和XSLT 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>
任何帮助将不胜感激。
答案 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>