3

I have this XML document:

</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>

and I need to convert it into the following XML document using XSLT:

<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>

I am able to get node values but not able to get node captions. How can I perform this conversion? I'm new to XSLT.

4

2 回答 2

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>
于 2012-09-12T09:01:25.633 回答
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>
于 2012-09-12T09:03:23.223 回答