我正在使用.NET4代码触发转换。
转换工作正常,当我直接在xslt中使用document函数编写xpath时(请参阅示例xslt中的元素PanelOK):
但是当xPath本身存储在变量中时,它不会起作用(参见PanelException元素):
<xsl:value-of select="@Customer"/>
其中@Customer的值为#34;文档(&#39; myXml.xml&#39;)/ COM:root / COM:Global / @ Customer&#34;
然后我用脚本扩展了我的xslt。当我没有在xpath中使用文档函数时,这可以正常工作,例如only / COM:root / COM:Global / @ Customer。但是对于文档函数,我得到异常此查询需要XsltContext,因为函数未知。
以下是示例:xml1具有属性customer,其值包含xpath表达式,xml2是可以找到值的文件,xslt是转换xml1并评估存储在属性customer中的xpath表达式的转换。应该使用自定义脚本在xml2中查找值,然后在select语句中出现excpetion。我该怎么做才能让它发挥作用?
XML1:
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<SFK:root xmlns:SFK="http://www.Test.com/SoftKeys">
<SFK:Panel Customer="document('setting.xml')/COM:root/COM:Global/@Customer">
</SFK:Panel>
</SFK:root>
XML2:
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
<COM:root xmlns:COM="http://www.Test.com/Comm">
<COM:Global Customer="Microsoft">
</COM:Global>
</COM:root>
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:dyn="http://exslt.org/dynamic"
xmlns:SFK="http://www.Test.com/SoftKeys"
xmlns:COM="http://www.Test.com/Comm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
extension-element-prefixes="dyn msxsl"
exclude-result-prefixes="msxsl xsl SFK COM dyn">
<!--Script to evaluate a string xPath to a Node. the real evaluate extension is not implemented in MS xslt processor-->
<msxsl:script implements-prefix="dyn" language="C#">
<![CDATA[
public XPathNodeIterator evaluate(XPathNavigator context, string expression)
{
XmlNamespaceManager mngr = new XmlNamespaceManager(new NameTable());
mngr.AddNamespace("SFK","http://www.Test.com/SoftKeys");
mngr.AddNamespace("COM","http://www.Test.com/Comm");
mngr.AddNamespace("msxsl","urn:schemas-microsoft-com:xslt");
return context.Select(expression,mngr); // here occurs the exception
}
]]>
</msxsl:script>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="current()/SFK:root/SFK:Panel"/>
</xsl:template>
<xsl:template match="SFK:Panel">
</PanelOk>
<xsl:value-of select="document('xml2.xml')/COM:root/COM:Global/@Customer"/>
</PanelOk>
</PanelException>
<xsl:value-of select="dyn:evaluate(., @Customer)"/>
</PanelException>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
我担心XPath规范中没有定义document
函数,因此在Microsoft的XPathNavigator等XPath 1.0实现中不可用。 document
函数仅在XSLT中定义。
我不确定建议什么,使用Saxon 9或XQSharp你可以使用XPath 2.0 doc
函数,但我不确定你是否想要从.NET框架的内置XSLT和XPath迁移1.0实现第三方XSLT和XPath 2.0实现。
答案 1 :(得分:1)
在Microsoft XSLT处理器中未实现EXSLT函数dyn:evaluate
。
如果所需XPath表达式的不同部分在xml1的单独元素/属性中编码,则可以解决此问题。
当然,这是一个非常有限的解决方案,需要约定和纪律。
即使在XSLT 2.0 / XPath2.0 中也不支持动态评估XPath表达式。此类支持可能在更高版本中提供,但3.0版本仍具有“工作草案”状态。