我有一个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>
我看过XSLT1.0-从变量中删除重复节点和XSLT1.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
的所有属性 - 引入一个元素
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>