Ank*_*ani 4 java xml xslt transformation
我是XSLT的初学者.
我的源XML如下:
<Passengers>
<Passenger type="A" id="P1"/>
<Passenger type="A" id="P2"/>
<Passenger type="B" id="P3"/>
<Passenger type="C" id="P4"/>
</Passengers>
Run Code Online (Sandbox Code Playgroud)
输出应如下:
<Pax_Items>
<Item>
<Type>A</Type>
<Count>2</Count>
</Item>
<Item>
<Type>B</Type>
<Count>1</Count>
</Item>
<Item>
<Type>C</Type>
<Count>1</Count>
</Item>
</Pax_Items>
Run Code Online (Sandbox Code Playgroud)
我已经创建了XSLT,如下所示
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" exclude-result-prefixes="xmlns">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:variable name="filter" select="'TK,AJ'"/>
<xsl:template match="Passengers">
<xsl:element name="Pax_Items">
<xsl:apply-templates select="Passenger"/>
</xsl:element>
</xsl:template>
<xsl:template match="Passenger">
<xsl:element name="Item">
<xsl:element name="Type">
<xsl:value-of select="@type"/>
</xsl:element>
<xsl:element name="Count">
<xsl:value-of select="count(//Passenger[@type=current()/@type])"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
使用上面的XSLT我得到以下输出:
<Pax_Items>
<Item>
<Type>A</Type>
<Count>2</Count>
</Item>
<Item>
<Type>A</Type>
<Count>2</Count>
</Item>
<Item>
<Type>B</Type>
<Count>1</Count>
</Item>
<Item>
<Type>C</Type>
<Count>1</Count>
</Item>
</Pax_Items>
Run Code Online (Sandbox Code Playgroud)
如何省略或跳过重复元素?请帮忙.
这实际上是分组问题的一个很好的例子.在XSLT1.0中,最有效的分组方法是使用一种称为"Muenchian分组"的技术,因此可能值得学习这一点.
在这种情况下,您希望按其@type属性对Passenger元素进行分组,因此您需要定义一个键来执行此操作
<xsl:key name="Passengers" match="Passenger" use="@type"/>
Run Code Online (Sandbox Code Playgroud)
然后,您需要选择Passenger元素,这些元素恰好是组中该元素首次出现的@type属性.这样做如下:
<xsl:apply-templates
select="Passenger[generate-id() = generate-id(key('Passengers', @type)[1])]"/>
Run Code Online (Sandbox Code Playgroud)
请注意使用generate-id为节点生成唯一ID,允许比较两个节点.
然后,为了计算组中出现的次数,它是直截了当的
<xsl:value-of select="count(key('Passengers', @type))"/>
Run Code Online (Sandbox Code Playgroud)
这是完整的XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="Passengers" match="Passenger" use="@type"/>
<xsl:template match="Passengers">
<Pax_Items>
<xsl:apply-templates select="Passenger[generate-id() = generate-id(key('Passengers', @type)[1])]"/>
</Pax_Items>
</xsl:template>
<xsl:template match="Passenger">
<Item>
<Type>
<xsl:value-of select="@type"/>
</Type>
<Count>
<xsl:value-of select="count(key('Passengers', @type))"/>
</Count>
</Item>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
应用于示例XML时,将输出以下内容
<Pax_Items>
<Item>
<Type>A</Type>
<Count>2</Count>
</Item>
<Item>
<Type>B</Type>
<Count>1</Count>
</Item>
<Item>
<Type>C</Type>
<Count>1</Count>
</Item>
</Pax_Items>
Run Code Online (Sandbox Code Playgroud)
另请注意,没有理由使用xsl:element来输出静态元素.直接写出元素.