使用XML和XSLT

时间:2011-09-29 19:31:54

标签: xml xslt xsd xml-parsing

我只是想创建一个带有XSL样式表的示例XML文件。问题是,当我解析这两个文件时,我得到一个奇怪的输出。

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

这是XSLT文件:

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

当我使用visual studio ide渲染两者时,我可以看到XML文件如何转换为XHTML。输出如下:

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

当我在浏览器中看到这个时,它很好,但是我不满意&lt; html&gt;&lt;身体&gt;&lt; / body&gt;&lt; / html&gt;显示更多一次。我做错了什么?

感谢 杰森

5 个答案:

答案 0 :(得分:1)

我已经根据我认为的问题编辑了你的问题,即body和html标签被包含两次。那是因为你匹配艺术家的模板两次。由于模板包含body和html标记,因此它们在输出中包含两次。

您需要使用for-each来匹配单个模板中的多个实例。以下摘自http://www.w3schools.com/举例:

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

查看w3school xsl部分了解更多基础知识: http://www.w3schools.com/xsl/

答案 1 :(得分:1)

您的match="Artist"模板已应用两次,因为源文档中有两个Artist。这就是结果树中的两个html元素。

尝试使用这个稍微修改过的样式表版本:

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

答案 2 :(得分:1)

您的第一个模板正在匹配多个Artist元素。对于匹配的每个Artist元素,它会将<html><body>...</>树输出到结果文档。您可以尝试以下内容。

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

答案 3 :(得分:1)

你有多个Artist元素,而“select”的匹配就是抓住它们。

答案 4 :(得分:0)

可能是最短的解决方案之一(没有模板匹配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>