开发者

Using XML and XSLT

I'm just trying to create an example XML file with an XSL style sheet. The problem is, when i parse the two files, i get a strange output.

here is the XML:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="mySchema.xsl"?>
<Artists>
  <Artist>
    <BandName>The Cure</BandName>
    <Albums>
      <Album>
        <AlbumTitle>Disintegration</AlbumTitle>
        <Tracks>
          <track>
            <Title>Plain Song</Title>
            <Order>1</Order>
            <Lenght>
              <min>5</min>
              <sec>12</sec>
            </Lenght>
          </track>
          <track>
            <Title>Pictures Of You</Title>
            <Order>2</Order>
            <Lenght>
              <min>7</min>
              <sec>24</sec>
            </Lenght>
          </track>
        </Tracks>
      </Album>
      <Album>
        <AlbumTitle>Wish</AlbumTitle>
        <Tracks>
          <track>
            <Title>A Letter To Elise</Title>
            <Order>4</Order>
            <Lenght>
              <min>5</min>
              <sec>14</sec>
            </Lenght>
          </track>
          <track>
            <Title>From the Edge of the Deep Green Sea</Title>
    开发者_如何转开发        <Order>2</Order>
            <Lenght>
              <min>7</min>
              <sec>45</sec>
            </Lenght>
          </track>
        </Tracks>
      </Album>
    </Albums>
  </Artist>

  <Artist>
    <BandName>The Pogues</BandName>
    <Albums>
      <Album>
        <AlbumTitle>If I Should Fall from Grace with God</AlbumTitle>
        <Tracks>
          <track>
            <Title>Fairytale of New York</Title>
            <Order>1</Order>
            <Lenght>
              <min>2</min>
              <sec>20</sec>
            </Lenght>
          </track>
          <track>
            <Title>Sit Down by the Fire</Title>
            <Order>13</Order>
            <Lenght>
              <min>4</min>
              <sec>10</sec>
            </Lenght>
          </track>
        </Tracks>
      </Album>
      <Album>
        <AlbumTitle>Peace And Love </AlbumTitle>
        <Tracks>
          <track>
            <Title>Young Ned Of The Hill</Title>
            <Order>3</Order>
            <Lenght>
              <min>2</min>
              <sec>45</sec>
            </Lenght>
          </track>
          <track>
            <Title>Boat Train</Title>
            <Order>11</Order>
            <Lenght>
              <min>2</min>
              <sec>40</sec>
            </Lenght>
          </track>
        </Tracks>
      </Album>
    </Albums>
  </Artist>
</Artists>

and here is the XSLT file:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="Artist">
    <html>
      <body>
        <xsl:apply-templates select="BandName"/>
        <br></br>
      </body>
    </html>

  </xsl:template>
  <xsl:template match="BandName">
    <b>Found a band!</b>
  </xsl:template>
</xsl:stylesheet>

When i render the two, using visual studio ide, i can see how the XML file transformed to XHTML. the output looks like this:

<?xml version="1.0" encoding="utf-8"?>
  <html><body><b>Found a band!</b><br /></body></html>

  <html><body><b>Found a band!</b><br /></body></html>

When i look at this in the browser, its fine, but i'm not happy how the < html >< body >< /body >< /html > is displayed more that once. What am i doing wrong?

thanks jason


Your match="Artist" template is getting applied twice because there are two Artist in your source document. This is what's resulting in two html elements in the result tree.

Try using this slightly modified version of your stylesheet:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="Artists">
    <html>
      <body>
        <xsl:apply-templates select="Artist"/>
        <br></br>
      </body>
    </html>    
  </xsl:template>

  <xsl:template match="Artist">
    <xsl:apply-templates select="BandName"/>
  </xsl:template>

  <xsl:template match="BandName">
    <b>Found a band!</b>
  </xsl:template>
</xsl:stylesheet>


I've edited your question to what I think the problem is, that the body and html tag are being included twice. That's because you're matching the template for Artist twice. Since the template includes both the body and html tags, they're being included twice in the output.

You need to use a for-each to match multiple instances in a single template. Below is an excerpt from http://www.w3schools.com/ giving an example:

<xsl:for-each select="catalog/cd">
    <tr>
        <td><xsl:value-of select="title"/></td>
        <td><xsl:value-of select="artist"/></td>
    </tr>
</xsl:for-each>

Check out the w3school xsl section for more basics: http://www.w3schools.com/xsl/


Your first template is matching multiple Artist elements. For each Artist element it matches, it is outputting your <html><body>...</> tree to the result document. You can try something like the following.

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

  <xsl:template match="/Artists">
    <html>
      <body>
        <xsl:apply-templates select="Artist/BandName"/>
        <br></br>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="BandName">
    <b>Found a band!</b>
  </xsl:template>

</xsl:stylesheet>


You have more than one Artist element and the match for "select" is grabbing both of them.


Probably one of the shortest possible solutions (no template matching Artist):

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

 <xsl:template match="/*">
  <html>
   <body>
    <xsl:apply-templates/>
   </body>
  </html>
 </xsl:template>

 <xsl:template match="Artist/BandName">
   <b>Found a band!</b><br /><br />
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜