我一直在尝试为此提出一个不错的解决方案,但我甚至找不到一个不雅的解决方案。
我有一个看起来像这样的XML文件:
<Root>
<Something>
<SomethingElse>Value of SomethingElse</SomethingElse>
</Something>
...
<Map>
<Node>
<Path>/Root/Something/SomethingElse</Path>
</Node>
<Map>
...
</Root>
我想要做的是编写一个XSL转换,它将采用<Path>
元素并将其text()
值用作XPath查询,以将转换应用于<SomethingElse>
元素,从而产生例如:
<text>Value of SomethingElse</text>
突然出现在我脑海中的第一件事就是:
<xsl:template match="Path">
<text><xsl:value-of select="{text()}"/></text>
</xsl:template>
但这当然不起作用,因为select
不是值属性。
我不知道如何解决这个问题。 Google搜索仅返回有关如何使用XPath获取文本值的结果,而不是相反。
我还想对返回的<SomethingElse>
元素应用进一步的转换,但是一旦我弄清楚如何执行此操作,这应该是一块蛋糕。
非常感谢这一切, Slampisko
答案 0 :(得分:2)
使用纯XSLT 1.0甚至2.0,您需要使用两个样式表,第一个接受输入并使用您想要使用的XPath表达式创建第二个样式表,然后针对原始输入运行第二个样式表。
或者您需要检查您的XSLT处理器是否支持扩展函数来将字符串计算为路径表达式,例如Saxon与http://www.saxonica.com/documentation/extensions/functions/evaluate.xml或AltovaXML之类的altova:evaluate函数http://manual.altova.com/AltovaXML/altovaxmlcommunity/index.html?xextaltova_general.htm。
答案 1 :(得分:2)
虽然完整的动态XPath评估不是XSLT 1.0 / XPath 1.0或XSLT 2.0 / XPath 2.0的一部分,但是可以生成一种XSLT 1.0实现,它可以以相当有限的方式工作 :
<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="text()"/>
<xsl:template match="Path" name="eval">
<xsl:param name="pPath" select="."/>
<xsl:param name="pContext" select="/"/>
<xsl:choose>
<!-- If there is something to evaluate -->
<xsl:when test="string-length($pPath) >0">
<xsl:variable name="vPath" select=
"substring($pPath,2)"/>
<xsl:variable name="vNameTest">
<xsl:choose>
<xsl:when test="not(contains($vPath, '/'))">
<xsl:value-of select="$vPath"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select=
"substring-before($vPath, '/')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="eval">
<xsl:with-param name="pPath" select=
"substring-after($pPath, $vNameTest)"/>
<xsl:with-param name="pContext" select=
"$pContext/*[name()=$vNameTest]"/>
</xsl:call-template>
</xsl:when>
<!-- Otherwise we have evaluated completely the path -->
<xsl:otherwise>
<xsl:copy-of select="$pContext"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<Root>
<Something>
<SomethingElse>Value of SomethingElse</SomethingElse>
</Something>
...
<Map>
<Node>
<Path>/Root/Something/SomethingElse</Path>
</Node>
</Map>
...
</Root>
产生了想要的正确结果:
<SomethingElse>Value of SomethingElse</SomethingElse>
我们假设以下限制:
我们评估的每个XPath表达式都必须由一系列名称测试组成,由XPath'/'运算符分隔 - 也就是说,每个位置步骤只指定一个元素名称。
< / LI>任何位置步骤都不能包含轴或谓词。