如何使用xslt 1.0分组xml节点

时间:2016-01-29 17:49:20

标签: xml xslt xslt-1.0

这是我的xml

<hotel>
    <rooms>
        <room>
            <rates>
                <rates id="1" adult="1" child="0"><rates>
                <rates id="2" adult="2" child="0"><rates>
                <rates id="3" adult="1" child="0"><rates>
            </rates>
        </room>
        <room>
            <rates>
                <rates id="4" adult="1" child="0"><rates>
                <rates id="5" adult="2" child="0"><rates>
                <rates id="6" adult="2" child="0"><rates>
            </rates>
        </room>
    </rooms>
</hotel>

如何使用xslt 1.0

基于“成人”和“儿童”制作分组

同一成人节点中的成人和孩子以及分组方式

结果我需要如下,

<hotel>
    <rooms>
        <room>
            <rates>
                <rates id="1" adult="1" child="0"><rates>
                <rates id="3" adult="1" child="0"><rates>
                <rates id="4" adult="1" child="0"><rates>
            </rates>
        </room>
        <room>
            <rates>
                <rates id="2" adult="2" child="0"><rates>
                <rates id="5" adult="2" child="0"><rates>
                <rates id="6" adult="2" child="0"><rates>
            </rates>
        </room>
    </rooms>
</hotel>

1 个答案:

答案 0 :(得分:0)

Example of Muenchian Grouping ...

XML输入(已修改为格式正确并添加child值的示例)

<hotel>
    <rooms>
        <room>
            <rates>
                <rates id="1" adult="1" child="0"/>
                <rates id="1A" adult="2" child="3"/>
                <rates id="2" adult="2" child="0"/>
                <rates id="3" adult="1" child="0"/>
            </rates>
        </room>
        <room>
            <rates>
                <rates id="4" adult="1" child="0"/>
                <rates id="5" adult="2" child="0"/>
                <rates id="6" adult="2" child="0"/>
                <rates id="6A" adult="2" child="3"/>
            </rates>
        </room>
    </rooms>
</hotel>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!--Group "rates" by combining the adult and child attribute values.-->
  <xsl:key name="rates" match="rates" use="concat(@adult,'|',@child)"/>

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

  <xsl:template match="rooms">
    <rooms>
      <!--
      This for-each will match the first "rates" element in each group.
      Nothing is done with the matched "rates" element; we only do this 
      to wrap the group with "room".
      -->
      <xsl:for-each select="room/rates/rates[count(.|key('rates',concat(@adult,'|',@child))[1])=1]">
        <room>
          <!--This apply-templates selects all "rates" in the group.-->
          <xsl:apply-templates select="key('rates',concat(@adult,'|',@child))"/>
        </room>
      </xsl:for-each>      
    </rooms>
  </xsl:template>

</xsl:stylesheet>

XML输出

<hotel>
   <rooms>
      <room>
         <rates id="1" adult="1" child="0"/>
         <rates id="3" adult="1" child="0"/>
         <rates id="4" adult="1" child="0"/>
      </room>
      <room>
         <rates id="1A" adult="2" child="3"/>
         <rates id="6A" adult="2" child="3"/>
      </room>
      <room>
         <rates id="2" adult="2" child="0"/>
         <rates id="5" adult="2" child="0"/>
         <rates id="6" adult="2" child="0"/>
      </room>
   </rooms>
</hotel>