[英]XML to XML with XSLT Sorting
I have a couple of huge XMLs and I need to sort only a some small portions of them. 我有几个巨大的XML,我只需要对其中的一小部分进行排序。 As output I should have the same XML but with sorted substructures. 作为输出,我应该具有相同的XML,但具有排序的子结构。 Here is an example: 这是一个例子:
<testStructure>
<parentStruct>
<firstpPreChild>some value here</firstpPreChild>
<secondPreChild>some other value</secondPreChild>
<thirdPreChild>third value here</thirdPreChild>
<fourtPreChild>fourth value here</fourtPreChild>
<struct id="5">
<num>5</num>
</struct>
<struct id="4">
<num>4</num>
</struct>
<struct id="1">
<num>1</num>
</struct>
<struct id="2">
<num>2</num>
</struct>
<struct id="3">
<num>3</num>
</struct>
<firstAdditionalChild>some value here</firstAdditionalChild>
<secondAdditionalChild>some other value</secondAdditionalChild>
<thirdAdditionalChild>third value here</thirdAdditionalChild>
<fourtAdditionalChild>fourth value here</fourtAdditionalChild>-->
</parentStruct>
<otherStruct>
<firstChild>some value here</firstChild>
<secondChild>some other value</secondChild>
<thirdChild>third value here</thirdChild>
<fourtChild>fourth value here</fourtChild>
</otherStruct>
should be transformed to 应该转化为
<testStructure>
<parentStruct>
<firstpPreChild>some value here</firstpPreChild>
<secondPreChild>some other value</secondPreChild>
<thirdPreChild>third value here</thirdPreChild>
<fourtPreChild>fourth value here</fourtPreChild>
<struct id="1">
<num>1</num>
</struct>
<struct id="2">
<num>2</num>
</struct>
<struct id="3">
<num>3</num>
</struct>
<struct id="4">
<num>4</num>
</struct>
<struct id="5">
<num>5</num>
</struct>
<firstAdditionalChild>some value here</firstAdditionalChild>
<secondAdditionalChild>some other value</secondAdditionalChild>
<thirdAdditionalChild>third value here</thirdAdditionalChild>
<fourtAdditionalChild>fourth value here</fourtAdditionalChild>-->
</parentStruct>
<otherStruct>
<firstChild>some value here</firstChild>
<secondChild>some other value</secondChild>
<thirdChild>third value here</thirdChild>
<fourtChild>fourth value here</fourtChild>
</otherStruct>
as sort criteria can be used either num
or @id
. 作为排序标准,可以使用num
或@id
。 I've tried some variation like this: 我试过这样的变体:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
which works, but shifts the sorted structure from its original position. 可以,但是将排序后的结构从其原始位置移开。 Unfortunately I need the same structure as output. 不幸的是,我需要与输出相同的结构。
Thanks in advance for the help! 先谢谢您的帮助!
Grouping by adjacent and then sorting, this XSLT 1.0 stylesheet: XSLT 1.0样式表按相邻分组然后排序:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kStructByFirstPreceding"
match="struct"
use="generate-id(
preceding-sibling::struct[
not(preceding-sibling::*[1]/self::struct)
][1]
)"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="struct[not(preceding-sibling::*[1]/self::struct)]">
<xsl:apply-templates select=".|key('kStructByFirstPreceding',
generate-id())"
mode="copy">
<xsl:sort select="@id"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="struct"/>
<xsl:template match="node()" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
</xsl:stylesheet>
Output: 输出:
<testStructure>
<parentStruct>
<firstpPreChild>some value here</firstpPreChild>
<secondPreChild>some other value</secondPreChild>
<thirdPreChild>third value here</thirdPreChild>
<fourtPreChild>fourth value here</fourtPreChild>
<struct id="1">
<num>1</num>
</struct>
<struct id="2">
<num>2</num>
</struct>
<struct id="3">
<num>3</num>
</struct>
<struct id="4">
<num>4</num>
</struct>
<struct id="5">
<num>5</num>
</struct>
<firstAdditionalChild>some value here</firstAdditionalChild>
<secondAdditionalChild>some other value</secondAdditionalChild>
<thirdAdditionalChild>third value here</thirdAdditionalChild>
<fourtAdditionalChild>fourth value here</fourtAdditionalChild>-->
</parentStruct>
<otherStruct>
<firstChild>some value here</firstChild>
<secondChild>some other value</secondChild>
<thirdChild>third value here</thirdChild>
<fourtChild>fourth value here</fourtChild>
</otherStruct>
</testStructure>
Simpler XSLT 2.0 solution: 更简单的XSLT 2.0解决方案:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[struct]">
<xsl:copy>
<xsl:for-each-group select="*"
group-adjacent="boolean(self::struct)">
<xsl:apply-templates select="current-group()">
<xsl:sort select="@id[current-grouping-key()]"/>
</xsl:apply-templates>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.