XSL和XPATH问题匹配

时间:2016-01-18 14:01:47

标签: xml xslt xpath

我有这个XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="cd.xsl"?>
    <produce>
        <item>apple<x>kk</x><y>jj</y></item>
        <item>banana<x>aaa</x></item>
        <item>pepper<x>qqq</x></item>
    </produce>

和这个XLS文件:

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

  <xsl:template match="/">
     <html>
    <body>
    <ul>
    <li><xsl:value-of select="node()"/></li>
    </ul>
    </body>
    </html>
  </xsl:template>
  </xsl:stylesheet>

我不明白&#34; /&#34;和&#34; / *&#34;匹配,因此我正在进行各种测试,例如上面的那些我得到了这个:

type="text/xsl" href="cd.xsl"

我不明白为什么。(我期待produce标签)。

但是如果我使用这个XLS文件:

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

      <xsl:template match="/*">
         <html>
        <body>
        <ul>
        <li><xsl:value-of select="node()"/></li>
        </ul>
        </body>
        </html>
      </xsl:template>
      </xsl:stylesheet>

我得到空页(只有标签li的黑点)。 你能解释一下这些差异吗?

1 个答案:

答案 0 :(得分:4)

  

如果您想了解XSL转换的作用,请使用能够显示实际结果代码的工具(例如xsltransform.net) - 而不是浏览器。 - michael.hor257k

我非常同意这一点,使用例如http://xsltransform.net/

TL; DR:/是文档节点,/*是输入文档的最外层元素

从第一个样式表获得的输出是

<html>
   <body>
      <ul>
         <li>type="text/xsl" href="cd.xsl"</li>
      </ul>
   </body>
</html>

我可以理解为什么这对你来说很惊讶。让我们看一下与文档节点匹配的XSLT代码:

<xsl:template match="/">

在此模板中,您对输入文档的唯一引用是

<xsl:value-of select="node()"/>

选择作为文档节点(/)的子节点的第一个节点的值。实际上,node()是一组节点,但在XSLT 1.0中,在这些上下文中,只使用了这样一个集合中的第一个项目。

那么,什么是节点?在XML文档模型(例如XDM)中,存在许多不同类型的节点,其中包括:元素节点,属性节点,处理指令。现在看看你的输入文件:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="cd.xsl"?>
<produce>
    <item>apple<x>kk</x><y>jj</y></item>
    <item>banana<x>aaa</x></item>
    <item>pepper<x>qqq</x></item>
</produce>

第一行是XML声明,它不是文档的一部分。第二行是一条处理指令,告诉您的浏览器在哪里查找XSLT样式表。处理指令文档的一部分。

此处理指令是文档节点的第一个子节点 - 这就是为什么您将其内容作为

的结果
<xsl:value-of select="node()"/>

从这一切可以看出,如果您从输入文档中删除处理指令,输出将如下所示

<html>
   <body>
      <ul>
         <li>
            applekkjj
                    bananaaaa
                    pepperqqq

         </li>
      </ul>
   </body>
</html>

因为现在,produce元素是/的第一个子节点。您看到的结果是produce元素的字符串值

另一方面,如果模板与/*匹配,则输出为空页,它是

<html>
   <body>
      <ul>
         <li>

         </li>
      </ul>
   </body>
</html>

/*表示XML文档的最外层元素,在本例中为produce。现在,produce元素是xsl:value-of上下文

<xsl:value-of select="node()"/>

同样,这将选择produce元素的第一个子节点 - 这是一个仅包含空格的文本节点