如果以下问题看似愚蠢,请抱歉,但由于我的经验不足,我不能确定这种方法的可靠性。
我正在尝试使用XSLT 1.0构建自己的XPath 1.0 位置路径评估程序。
这个想法很简单。转换接受输入xpath表达式以进行评估,然后将模板应用于所选节点。定义每种节点的模板以在输出上复制节点(以及一些更多信息)。输入文档将使用符合XSLT 1.0标准的处理器进行转换。
我想从您的专业知识中了解到,这种方法是否绝对,是否采用免费且可靠方式来测试位置路径和显示所选节点集。我不是要求有人调试我的代码。我已针对各种输入文档进行了测试,看起来工作正常。我想知道从XPath的角度来看我是否遗漏了什么。
这是否可以正确使用任何 XPath 1.0 位置路径?
这是否仅限于XPath 1.0 / XSLT 1.0?我没有看到任何通过更改其版本(显然是XSLT处理器)将模板扩展到XPath 2.0的说明。
这是应该用作XPath测试器的转换。注意:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="path-expr" select="*"/>
<xsl:template match="/">
<xpath-tester>
<node-sets count="{count($path-expr)}">
<xsl:apply-templates select="$path-expr" mode="path-expr"/>
</node-sets>
</xpath-tester>
</xsl:template>
<xsl:template match="node()|@*" mode="path-expr">
<node-set
position="{position()}"
id="{generate-id()}"
parent-id="{name(parent::*[1])}-{generate-id(parent::*[1])}">
<xsl:apply-templates select="." mode="output"/>
</node-set>
</xsl:template>
<xsl:template match="*" mode="output">
<xsl:attribute name="type">element</xsl:attribute>
<node>
<xsl:copy-of select="."/>
</node>
</xsl:template>
<xsl:template match="@*" mode="output">
<xsl:attribute name="type">attribute</xsl:attribute>
<node>
<xsl:copy-of select="."/>
</node>
</xsl:template>
<xsl:template match="text()" mode="output">
<xsl:attribute name="type">text</xsl:attribute>
<node>
<xsl:copy-of select="."/>
</node>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
听起来像我的宠物项目;随便看看我的代码,它有点太大了,不能贴在这里:
http://www.flynn1179.net/xml/FullDisplayXml.xslt
它将任何XML文档转换为具有可折叠节点的html页面,并通过修改顶部附近的键的“匹配”属性,您可以为节点指定XPath,并让它生成它们的列表或突出显示它们在源头。
我在这里问了一个非常类似的问题:How can you pass in a parameter to an xslt that can be used in a xsl:key?,虽然我试图将参数应用到密钥,但这不起作用。
注意:那段代码是正在进行中的工作,它在某些地方很难看,而且我很确定有一些东西它没有正确处理,或者可以做得更好,但希望它有用。我在我的XML沙箱页面上使用它的衍生物:http://www.flynn1179.net/xml/(这也是一项正在进行中的工作,我知道其中有一些错误)答案 1 :(得分:1)
您可能有兴趣查看我11岁 XPath Vizualizer 的代码。
在XSLT 2.0中不直接支持XSLT内部的动态评估,并且在XSLT 3.0 / XPath 3.0中可能存在这样的支持,这根本不是必需的。
答案 2 :(得分:0)
首先@Martin指出
您需要支持动态XPath评估才能将XPath作为节点集处理
为了处理动态XPath评估,我对转换进行了一些扩展。转换现在能够接受输入字符串并将其评估为XPath。
现在使用saxon:evaluate
依赖萨克森。以类似的方式并且在function-available
的支持下,可以实现其他扩展并使其更加便携。
这里有三个新模板(以及两个新参数)替换原始转换中的根模板(给定命名空间声明xmlns:saxon="http://icl.com/saxon"
)。
<xsl:param name="path-expr" select="false()"/>
<xsl:param name="xpath" select="*"/>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="$path-expr">
<xsl:apply-templates select="/" mode="dyn"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="/" mode="base"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/" mode="dyn">
<xpath-tester>
<node-sets count="{count(saxon:evaluate($path-expr))}">
<xsl:apply-templates select="saxon:evaluate($path-expr)"
mode="path-expr"/>
</node-sets>
</xpath-tester>
</xsl:template>
<xsl:template match="/" mode="base">
<xpath-tester>
<node-sets count="{count($xpath)}">
<xsl:apply-templates select="$xpath"
mode="path-expr"/>
</node-sets>
</xpath-tester>
</xsl:template>
第二个@Martin指出
我怀疑你一起输出属性和元素节点会遇到麻烦
我已经进行了测试并遇到了这个问题,但是如上所述,即使在那种情况下也能正常工作。