English 中文(简体)
使用XSLT排序的XML到XML
原标题:XML to XML with XSLT Sorting
  • 时间:2011-02-14 12:45:53
  •  标签:
  • xml
  • xslt

I have a couple of huge XMLs and I need to sort only a some small portions of them. As output I should have the same XML but with sorted substructures. 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>

应转换为

<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. I ve tried some variation like this:

<xsl:template match="node()|@*">
<xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

这起作用,但将排序后的结构从其原始位置移位。不幸的是,我需要与输出相同的结构。

提前感谢您的帮助!

问题回答

此XSLT1.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>

输出:

<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>--&gt; 
    </parentStruct>
    <otherStruct>
        <firstChild>some value here</firstChild>
        <secondChild>some other value</secondChild>
        <thirdChild>third value here</thirdChild>
        <fourtChild>fourth value here</fourtChild>
    </otherStruct>
</testStructure>

更简单的XSLT2.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>




相关问题
how to represent it in dtd?

I have two element action and guid. guid is a required field when action is add. but when action is del it will not appear in file. How to represent this in dtd ?

.Net application configuration add xml-data

I need to add xml-content to my application configuration file. Is there a way to add it directly to the appSettings section or do I need to implement a configSection? Is it possible to add the xml ...

XStream serializing collections

I have a class structure that I would like to serialize with Xstream. The root class contains a collection of other objects (of varying types). I would like to only serialize part of the objects that ...

MS Word splits words in its XML format

I have a Word 2003 document saved as a XML in WordProcessingML format. It contains few placeholders which will be dynamically replaced by an appropriate content. But, the problem is that Word ...

Merging an XML file with a list of changes

I have two XML files that are generated by another application I have no control over. The first is a settings file, and the second is a list of changes that should be applied to the first. Main ...

How do I check if a node has no siblings?

I have a org.w3c.dom.Node object. I would like to see if it has any other siblings. Here s what I have tried: Node sibling = node.getNextSibling(); if(sibling == null) return true; else ...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

热门标签