使用XSLT获取节点标题

时间:2012-09-12 08:33:02

标签: xml xslt

我有这个XML文档:

</Items>
<Item>
  <Id>1</Id>
  <Weekday>4</Weekday>
  <WeekdayName>Wednesday</WeekdayName>
  <Hour0>12</Hour0>
  <Hour1>5</Hour1>
  <Hour2>9</Hour2>
</Item>
<Item>
  <Id>1</Id>
  <Weekday>5</Weekday>
  <WeekdayName>Thursday</WeekdayName>
  <Hour0>10</Hour0>
  <Hour1>8</Hour1>
  <Hour2>15</Hour2>
</Item>
</Items>

我需要使用XSLT将其转换为以下XML文档:

<report>
  <categories>
    <category label="Hour1"/>
    <category label="Hour2"/>
    <category label="Hour3"/>
  </categories>
  <dataset day="Wednesday">
   <set value="12"/>
   <set value="5"/>
   <set value="9"/>
  </dataset>
  <dataset day="Thursday">
   <set value="10"/>
   <set value="8"/>
   <set value="15"/>
  </dataset>
</report>

我能够获取节点值但无法获取节点标题。我该如何进行此转换?我是XSLT的新手。

2 个答案:

答案 0 :(得分:3)

我认为你的意思是输出文件中没有Hour0,Hour2等。

试试这个XSLT 1.0样式表...

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

<xsl:template match="@*|node()" />

<xsl:template match="/">
  <report>
    <categories>
      <xsl:apply-templates select="*/Item[1]/*[starts-with(name(),'Hour')]" mode="category" />
    </categories>
    <xsl:apply-templates select="*/Item"/>
  </report>
</xsl:template>

<xsl:template match="Item">
  <dataset day="{WeekdayName}">
    <xsl:apply-templates select="*[starts-with(name(),'Hour')]" mode="set" />  
  </dataset>
</xsl:template>

<xsl:template match="*[starts-with(name(),'Hour')]" mode="category">
  <category label="{name()}" />
</xsl:template>

<xsl:template match="*[starts-with(name(),'Hour')]" mode="set">
  <set value="{.}"/>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

这是另一种选择 - 它是相当机械的,并假设小时节点的顺序始终相同。肖恩看起来更优雅。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" indent="yes"/>

    <xsl:template match="/Items">
        <report>
            <categories>
                <xsl:for-each select="Item[1]/*[substring(local-name(), 1, 4)='Hour']">
                    <xsl:element name="category">
                        <xsl:attribute name="label">
                            <xsl:value-of select="local-name()"/>
                        </xsl:attribute>
                    </xsl:element>
                </xsl:for-each>
            </categories>
            <xsl:apply-templates select="Item"/>
        </report>
    </xsl:template>

    <xsl:template match="Item">
        <xsl:element name="dataset">
            <xsl:attribute name="day">
                <xsl:value-of select="WeekdayName"/>
            </xsl:attribute>
            <xsl:for-each select="*[substring(local-name(), 1, 4)='Hour']">
                <xsl:element name="set">
                    <xsl:attribute name="value">
                        <xsl:value-of select="text()"/>
                    </xsl:attribute>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>