无法使用xsl从xml文档中检索信息

时间:2013-08-15 20:33:31

标签: xml xslt xpath

我开始学习xml和xsl,但由于某种原因,我不能让xpath在xsl中工作。我的xml文档是否以错误的方式构建,或者为什么不是表中显示的游戏14的价格?

我的xsl尝试非常简单:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
  <h2>My Games</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Game Name</th>
        <th>Price</th>
      </tr>
      <tr>
        <td><xsl:value-of select=
            "Xboxspellen/Spellen/Spel[14]/Spelnaam"/></td>
        <td><xsl:value-of select=
            "Xboxspellen/Spellen/Spel[14]/Prijs"/></td>
      </tr>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

更短版本的xml代码:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Xboxspellen.xsl"?>
<Xboxspellen xmlns="http://www.w3schools.com" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://www.w3schools.com 
                                 Xboxspellen.xsd">
  <Genres>
    ...
    <Genre id="Adv">
      <Genrenaam>Adventure</Genrenaam>
      <Spel idref="12"/>
      <Spel idref="13"/>
      <Spel idref="14"/>
    </Genre>
  </Genres>

  <Spellen>
    ...
    ...
    <Spel id="14">
      <Spelnaam>Omerta: city of gangsters</Spelnaam>
      <Uitgever>Kalypso</Uitgever>
      <Prijs>49.98</Prijs>
      <Leeftijd>16</Leeftijd>
      <Aankoop>
        <Dag>28</Dag>
        <Maand>04</Maand>
        <Jaar>2011</Jaar>
      </Aankoop>
      <Afbeelding>spel14.jpg</Afbeelding>
    </Spel>
  </Spellen>
</Xboxspellen>

我一直在尝试几个小时,但似乎没有找到答案,如果有人能帮助我,我会非常感激:D

2 个答案:

答案 0 :(得分:1)

xmlns:w3="http://www.w3schools.com"添加到xsl:stylesheet元素。

并将w3前缀添加到select语句中的元素:

    <td><xsl:value-of select=
        "w3:Xboxspellen/w3:Spellen/w3:Spel[@id='14']/w3:Spelnaam"/></td>
    <td><xsl:value-of select=
        "w3:Xboxspellen/w3:Spellen/w3:Spel[@id='14']/w3:Prijs"/></td>

您的xml位于默认命名空间“http://www.w3schools.com”中, 但是xsl select中的xpath位于null命名空间中。 他们不匹配。命名空间匹配不是前缀(或缺少前缀) 但是由前缀绑定的名称空间。

{http://www.w3schools.com}/Xboxspellen != {}/Xboxspellen

有关详情,请参阅此处:XML Namespaces and How They Affect XPath and XSLT

另外:The perils of default namespaces

注意:我将“[14]”更改为“[@ id ='14']”以使其适用于您的示例。 如果该元素实际上是序列中的第14个,则您不需要 改变这一点。但如果你有id,那么我可能会依赖它们 而非数数。

答案 1 :(得分:1)

你已经有了一个良好的开端。现在,你已经在每个人迟早会遇到的经典故事中磕磕绊绊:你已经编写了一个像Xboxspellen/Spellen/Spel[14]/Spelnaam这样的XPath表达式,并期望它与你文档中的元素相匹配。但是文档中的元素没有命名为Xboxspellen等。它们是名称空间限定的,并且它们都在范围内具有默认名称空间声明(xmlns="..."),因此它们的完整(扩展)名称不是Xboxspellen等,而是{http://www.w3schools.com}Xboxspellen{http://www.w3schools.com}Spellen

通过使XPath表达式和XML在事物名称上达成一致来纠正这种情况。通常情况下,这意味着:

  1. 向XSLT样式表添加名称空间声明,将一些前缀(与哪个前缀无关)绑定到XML中使用的名称空间:

    xmlns:w3s =“http://www.w3schools.com

  2. 在XPath表达式中使用该前缀:

    <td><xsl:value-of select="w3s:Xboxspellen
                              /w3s:Spellen
                              /w3s:Spel[14]
                              /w3s:Spelnaam" /></td>
    <td><xsl:value-of select="w3s:Xboxspellen
                              /w3s:Spellen
                              /w3s:Spel[14]
                              /w3s:Prijs"/></td>
    
  3. (我在XPath中删除了易读性的行;在XPath表达式中,空格是合法的,这也是一件好事。)

    现在XPath表达式将匹配。