我正在尝试重新排列一组XML节点以进行进一步处理。 基本思想是我需要使用高效的XSLT处理来更改节点的分组。
我的输入结构是:
<all_nodes>
<student>
<math>
<record>
<detail1/>
<detail2/>
</record>
</math>
<science>
<record>
<detail1/>
<detail2/>
</record>
</science>
<history>
<record>
<detail1/>
<detail2/>
</record>
</history>
</student>
<student>
<math>
<record>
<detail1/>
<detail2/>
</record>
</math>
<science>
<record>
<detail1/>
<detail2/>
</record>
</science>
<history>
<record>
<detail1/>
<detail2/>
</record>
</history>
</student>
</all_nodes>
所需的输出按主题分组。
请注意,student
节点已被删除,因为它不需要
我只需要将record
节点与共同主题父节点组合在一起:
<all_nodes>
<math>
<record>
<detail1/>
<detail2/>
</record>
<record>
<detail1/>
<detail2/>
</record>
</math>
<science>
<record>
<detail1/>
<detail2/>
</record>
<record>
<detail1/>
<detail2/>
</record>
</science>
<history>
<record>
<detail1/>
<detail2/>
</record>
<record>
<detail1/>
<detail2/>
</record>
</history>
</all_nodes>
我能够通过使用以下代码实现所需的输出,但我认为可能有更好的方法。 你能告诉我如何改进代码吗?
<xsl:template match="/">
<xsl:call-template name="math"/>
<xsl:call-template name="science"/>
<xsl:call-template name="history"/>
</xsl:template>
<xsl:template name="math">
<xsl:element name="math">
<xsl:apply-templates select="//math/record" />
</xsl:element>
</xsl:template>
<xsl:template name="science">
<xsl:element name="science">
<xsl:apply-templates select="//science/record" />
</xsl:element>
</xsl:template>
<xsl:template name="history">
<xsl:element name="history">
<xsl:apply-templates select="//history/record" />
</xsl:element>
</xsl:template>
<xsl:template match="record">
<xsl:copy-of select="."/>
</xsl:template>
谢谢!
答案 0 :(得分:1)
如果它总是只是三个已知主题,那么你可以这么简单地做到:
[deleted]
编辑:实际上,使用密钥不太可能带来显着优势,所以为什么不让它更简单:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/all_nodes">
<xsl:copy>
<math>
<xsl:copy-of select="student/math/record"/>
</math>
<science>
<xsl:copy-of select="student/science/record"/>
</science>
<history>
<xsl:copy-of select="student/history/record"/>
</history>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
使用 XSLT 2.0 的更通用的实现,它支持任何主题,而不在样式表中明确枚举它们:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each-group select="*/*/*" group-by="local-name(..)">
<xsl:element name="{current-grouping-key()}">
<xsl:copy-of select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>