使用XSL对XML进行分组

时间:2014-07-01 08:40:18

标签: xml xslt-1.0

我对分组有点困惑。我有以下XML代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <isif_data>
        <date>29.05.
            <event-date>
                <type>type1</type>
                <Time Timesort="1845">18.45</Time>
                <title>event1</title>
                <cell/>
                <place>abc</place>
            </event-date>
            <event-date>
                <type>type1</type>
                <Time Timesort="0900">9</Time>
                <title>event2</title>
                <cell/>
                <place>abd</place>
            </event-date>
            <event-date>
                <type>type2</type>
                <Time Timesort="1930">19.30</Time>
                <title>event3</title>
                <cell/>
                <place>abe</place>
            </event-date>
            <event-date>
                <type>type2</type>
                <Time Timesort="1900">19</Time>
                <title>event4</title>
                <cell/>
                <place>abf</place>
            </event-date>
        </date>
        <date>30.05.
            <event-date>
                <type>type1</type>
                <Time Timesort="1845">18.45</Time>
                <title>event5</title>
                <cell/>
                <place>abg</place>
            </event-date>
            <event-date>
                <type>type2</type>
                <Time Timesort="0900">9</Time>
                <title>event6</title>
                <cell/>
                <place>abh</place>
            </event-date>
            <event-date>
                <type>type1        </type>
                <Time Timesort="1500">15</Time>
                <title>event7</title>
                <cell/>
                <place>abi</place>
            </event-date>
            <event-date>
                <type>type2</type>
                <Time Timesort="1700">17</Time>
                <title>event8</title>
                <cell/>
                <place>abj</place>
            </event-date>
        </date>
    </isif_data>

现在我需要生成的XML看起来像这样:

    <?xml version="1.0" encoding="UTF-8"?>
    <isif_data>
     <date>29.05.</date>
     <type>type1</type>
     <Time>9</Time>
     <title>event2</title>
     <cell/>
     <place>abd</place>
     <Time>18.45</Time>
     <title>event1</title>
     <cell/>
     <place>abc</place>
     <type>type2</type>
     <Time>19</Time>
     <title>event4</title>
     <cell/>
     <place>abf</place>
     <Time>19.30</Time>
     <title>event3</title>
     <cell/>
     <place>abe</place>
     <date>30.05.</date>
     <type>type1</type>
     <Time>15</Time>
     <title>event7</title>
     <cell/>
     <place>abi</place>
     <Time>18.45</Time>
     <title>event5</title>
     <cell/>
     <place>abg</place>
     <type>type2</type>
     <Time>9</Time>
     <title>event6</title>
     <cell/>
     <place>abh</place>
     <Time>17</Time>
     <title>event8</title>
     <cell/>
     <place>abj</place>
    </isif_data>

我尝试使用Muenchian方法,但我从来没有像我想的那样工作。这里的任何人,谁知道如何让它工作?我需要使用xsl版本1.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" encoding="UTF-8" indent="yes" />
    <xsl:key name="type" match="event-date" use="type" />
     <xsl:template match="isif_data">
      <xsl:element name="isif_data">
       <xsl:for-each select="date">
        <xsl:element name="date"><xsl:value-of select="date"/></xsl:element>
        <xsl:element name="cell"/>
         <xsl:for-each select="event-date[count(. | key('type', type)[1]) = 1]">
          <xsl:sort select="time/@Timesort" />
           <xsl:call-template name="type" />
            <xsl:for-each select="key('type', type)">
             <xsl:call-template name="time" />
             <xsl:call-template name="title" />
             <xsl:call-template name="place" />
            </xsl:for-each>
           </xsl:for-each>
        </xsl:for-each>
       </xsl:element>
      </xsl:template>
     </xsl:stylesheet>

如果您需要模板,我也可以提供。我不确定他们是否需要它们。

2 个答案:

答案 0 :(得分:0)

  

是否有可能为每个日期标记创建一个组   原始代码?

此:

<xsl:key name="type" match="event-date" use="type" />
无论日期如何,

都会按类型对所有事件日期进行分组。由于您希望按类型在每个日期内对事件进行分组,因此您需要在密钥中同时使用日期和类型:

<xsl:key name="type" match="event-date" use="concat (../., '|', type)" />

答案 1 :(得分:0)

如果我假设有或没有空格的类型应该被分组,你确实需要进行键控,因为需要进行空间的规范化。然后它看起来像:

 <?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="types" match="event-date"
      use="concat(normalize-space(../text()), normalize-space(type))"/>
   <xsl:template match="event-date">
     <xsl:variable name="thisType" select="normalize-space(type)"/>
     <xsl:variable name="thisSet"
        select="key('types', concat(normalize-space(../text()), $thisType))"/>
     <xsl:if test="count(. | $thisSet[1]) = 1">
       <type><xsl:value-of select="$thisType"/>
       <xsl:for-each select="$thisSet">
         <xsl:apply-templates select="node()"/>
       </xsl:for-each>
       </type>
     </xsl:if>
   </xsl:template>
   <xsl:template match="type"/>
   <xsl:template match="node()">
     <xsl:copy>
       <xsl:copy-of select="@*" />
       <xsl:apply-templates select="node()" />
     </xsl:copy>
   </xsl:template>
 </xsl:stylesheet>

没有空间等,你不需要整个键控的东西。然后它看起来像:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template
    match="event-date[not(type = preceding-sibling::*/type)]">
    <type><xsl:value-of select="type"/>
    <xsl:apply-templates select="../*[type=current()/type]/node()"/>
    </type>
  </xsl:template>
  <xsl:template match="event-date | type"/>
  <xsl:template match="node()">
    <xsl:copy>
      <xsl:copy-of select="@*" />
      <xsl:apply-templates select="node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>