xslt分组和删除重复项

时间:2015-05-21 16:27:02

标签: xml xslt xslt-1.0 xslt-grouping muenchian-grouping

NSUserDefaults

我有这个xml,我需要将它分组到以下输出并添加inno和onno元素以给sumno。并检查indate和ondate以给予更大的支持。并且每当inno / onno / indate / ondate不存在时给出空元素。并删除重复项。如何用muenchian方法写这个

输出:

Keychain

我使用此xsl进行分组但无法添加和删除重复项

<Items>
    <array>
        <item name="A">
            <name>A</name>
            <indate>20141112</indate>
            <inno>2</inno>
            <status>1</status>
            <level>12</level>
            <size>.1</size>
            <text>item a text </text>
        </item>
        <item name="B">
            <name>B</name>
            <indate>20141012</indate>
            <inno>5</inno>
            <status>1</status>
            <level>13</level>
            <size>.5</size>
            <text>item b text </text>
        </item>
        <item name="C">
            <name>C</name>
            <indate>20140912</indate>
            <inno>6</inno>
            <status>1</status>
            <level>12</level>
            <size>.2</size>
            <text>item c text </text>
        </item>
        <item name="A">
            <name>A</name>
            <ondate>20140612</ondate>
            <onno>9</onno>
        </item>
        <item name="B">
            <name>B</name>
            <ondate>20140212</ondate>
            <inno>7</inno>
        </item>
        <item name="D">
            <name>D</name>
            <indate>20140712</indate>
            <inno>9</inno>
        </item>
        <item name="A">
            <name>A</name>
            <status>1</status>
            <level>12</level>
            <size>.1</size>
            <text>item a text </text>
        </item>
        <item name="B">
            <name>B</name>
            <status>1</status>
            <level>13</level>
            <size>.5</size>
            <text>item b text </text>
        </item>
        <item name="D">
            <name>D</name>
            <status>1</status>
            <level>13</level>
            <size>.9</size>
            <text>item d text </text>
        </item>
    </array>
</Items>

1 个答案:

答案 0 :(得分:1)

我认为您的代码通过item子元素正确地对name元素进行了分组。您似乎也希望消除重复的子元素,我不确定您是仅按元素名称还是按元素名称和元素内容来执行此操作。如果您想按元素名称进行操作,则可以定义第二个键<xsl:key name="duplicated-elements" match="item/*" use="concat(../name, '|', local-name())"/>

至于添加空元素,您需要检查它们是否存在。

以下是带有此类检查的样式表和第二个密钥:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="items-by-id" match="item[@name]" use="name"/>
  <xsl:key name="duplicated-elements" match="item/*" use="concat(../name, '|', local-name())"/>

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

  <xsl:template match="array">
    <xsl:copy>
      <xsl:apply-templates select="item[@name][generate-id() = generate-id(key('items-by-id', name)[1])]" mode="group"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="item[@name]" mode="group">
    <xsl:copy>
      <xsl:variable name="current-group" select="key('items-by-id', name)"/>
      <xsl:copy-of select="name"/>

      <xsl:choose>
        <xsl:when test="$current-group/indate">
          <xsl:apply-templates select="$current-group/indate"/>
        </xsl:when>
        <xsl:otherwise>
          <indate/>
        </xsl:otherwise>
      </xsl:choose>

      <xsl:choose>
        <xsl:when test="$current-group/inno">
          <xsl:apply-templates select="$current-group/inno"/>
        </xsl:when>
        <xsl:otherwise>
          <inno/>
        </xsl:otherwise>
      </xsl:choose>

      <xsl:choose>
        <xsl:when test="$current-group/ondate">
          <xsl:apply-templates select="$current-group/ondate"/>
        </xsl:when>
        <xsl:otherwise>
          <ondate/>
        </xsl:otherwise>
      </xsl:choose>

      <xsl:choose>
        <xsl:when test="$current-group/onno">
          <xsl:apply-templates select="$current-group/onno"/>
        </xsl:when>
        <xsl:otherwise>
          <onno/>
        </xsl:otherwise>
      </xsl:choose>

      <latedate>
        <xsl:choose>
          <xsl:when test="$current-group/indate > $current-group/ondate">
            <xsl:value-of select="$current-group/indate"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="$current-group/ondate"/>
          </xsl:otherwise>
        </xsl:choose>
      </latedate>

      <sumno>
        <xsl:value-of select="sum($current-group/inno | $current-group/onno)"/>
      </sumno>

      <xsl:apply-templates select="key('items-by-id', name)/*[not(self::name | self::indate | self::inno | self::ondate | self::onno)][generate-id() = generate-id(key('duplicated-elements', concat(../name, '|', local-name()))[1])]"/>
  </xsl:copy>
</xsl:template>


</xsl:stylesheet>

还有一些问题,比如检查不存在的日期,但我希望你能解决它。