使用XSLT v1对XML元素进行分组

时间:2013-02-20 12:04:37

标签: xml xslt-1.0

这对某些人来说似乎是一个简单的问题,但对我而言,现在已经过了几天。

我想更改此XML:

<?xml version="1.0" encoding="UTF-8"?>
<questionnaire>
  <Id>questionnaireId</Id>
  <Desc>questionnnaireDesc here</Desc>
  <QuestParts>
    <part>
      <partNumber>1</partNumber>
      <questItems>
         <item>
              <itemId>1</itemId>
              <itemText>The first item</itemText>
         </item>
      </questItems>
    </part>
    <part>
      <partNumber>1</partNumber>
      <questItems>
         <item>
              <itemId>2</itemId>
              <itemText>The second item</itemText>
         </item>
      </questItems>
    </part>
    <part>
      <partNumber>2</partNumber>
      <questItems>
         <item>
              <itemId>3</itemId>
              <itemText>A third item, but inside part 2</itemText>
         </item>
      </questItems>
    </part>
    <part>
      <partNumber>2</partNumber>
      <questItems>
         <item>
              <itemId>4</itemId>
              <itemText>A fourth item, but inside part 2</itemText>
         </item>
      </questItems>
    </part>
  </QuestParts>
</questionnaire>

到此:

<questionnaire>
  <Id>questionnaireId</Id>
  <Desc>questionnnaireDesc here</Desc>
  <QuestParts>
    <part>
      <partNumber>1</partNumber>
      <questItems>
         <item>
              <itemId>1</itemId>
              <itemText>The first item</itemText>
         </item>
         <item>
              <itemId>2</itemId>
              <itemText>The second item</itemText>
         </item>
      </questItems>
    </part>
    <part>
      <partNumber>2</partNumber>
      <questItems>
         <item>
              <itemId>3</itemId>
              <itemText>A third item, but inside part 2</itemText>
         </item>
         <item>
              <itemId>4</itemId>
              <itemText>A fourth item, but inside part 2</itemText>
         </item>
      </questItems>
    </part>
  </QuestParts>
</questionnaire>

换句话说,我只是想删除重复的元素,并将属于该部分的所有项目分组到该部分的元素中。

我已经通过多种方式尝试过,虽然有很多例子,但我找不到任何对我有用的东西,而且我还想避免再花2天时间与其他人一起努力在5分钟内解决。

非常感谢帮助。

格雷格

1 个答案:

答案 0 :(得分:0)

格雷格,

通过指向示例的链接,我设法使用以下XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<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:key name="partnr" match="part" use="partNumber" />

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

    <xsl:template match="QuestParts">
        <QuestParts>
            <xsl:for-each select="part[generate-id(.)=generate-id(key('partnr',partNumber))]">
                <xsl:variable name="curpartnr" select="partNumber" />
                <partNumber><xsl:value-of select="$curpartnr" /></partNumber>

                <questItems>
                    <xsl:for-each select="../part[generate-id(.)=generate-id(key('partnr',partNumber))]/questItems/item">
                         <item>
                              <itemId><xsl:value-of select="itemId" /></itemId>
                              <itemText><xsl:value-of select="itemText" /></itemText>
                         </item>
                    </xsl:for-each>
                </questItems>
            </xsl:for-each>
        </QuestParts>
    </xsl:template>
</xsl:stylesheet>

希望它有所帮助。