我正在开发一个使用XSLT转换HTML字符串以提取某些特定值的项目。你能看一下下面的HTML / XSLT,看看我做错了什么?
顺便说一句在下面的HTML中,我需要从<a>
中提取“某事”的值(XPATH = // div [@ id ='result'] / div [2] / div [1] / a [1]):
<html>
<head></head>
<body>
<div>
<div id="whatever">
<!--other stuff-->
</div>
<div id="whatever2">
<!--other stuff-->
<div>
<div class='listtable'>
<div>
<div id="result">
<div class="ignore">
<!--other stuff-->
</div>
<div>
<div>
<a>something</a>
</div>
</div>
</div>
</div>
<div>
<div id="result">
<div class="ignore">
<!--other stuff-->
</div>
<div>
<div>
<a>something</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
所以,XSLT我看起来像这样,但它不起作用......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My Link Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
</tr>
<xsl:for-each select="//div[@id='result']">
<tr>
<td><xsl:value-of select="/div[2]/div[1]/a[1]"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
P.S。:之前我曾与XPATHS合作,但我没有使用XSLT的经验,无论出于什么原因,当我尝试调试时Visual Studio崩溃,所以我不知道这里出了什么问题。
感谢您的帮助!
答案 0 :(得分:3)
了解 相对和绝对 XPath表达式之间的区别非常重要。
绝对XPath表达式以字符'/'开始。
/div[2]/div[1]/a[1]
如果XML文档的顶部元素未命名为div
,则不选择任何内容
另一方面,<xsl:for-each>
内或<xsl:template>
内的XPath表达式通常用于选择当前节点之外的节点。为此,他们必须相对。
相对 XPath表达式永远不会以'/'开始。
因此,在您的情况下,您需要:
div[2]/div[1]/a[1]
答案 1 :(得分:2)
我做错了什么?
这只是你提交的一个小错误。 XPath应该是:
"div[2]/div[1]/a[1]"
通过这种方式,您可以从xsl:for-each
的当前上下文开始正确选择元素。在您提供的方式中(使用XPath开头的转发),您将尝试从输入文档的根目录开始选择元素。
无论出于什么原因,当我尝试调试时Visual Studio崩溃,所以我不知道这里出了什么问题。
如果Visual Studio崩溃可能是因为其中存在一些漏洞。可能你需要一些补丁。您提供的XSLT是正确的,并且永远不会崩溃与XSLT处理器。您应该使用以下相同的转换获得成功的结果:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My Link Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
</tr>
<xsl:apply-templates select="//div[@id='result']"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="div[@id='result']">
<tr>
<td><xsl:value-of select="div[2]/div[1]/a[1]"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>