【问题标题】:document function in xsltxslt 中的文档功能
【发布时间】:2011-06-21 11:15:13
【问题描述】:

我正在使用 .NET4 代码触发转换。

当我直接在 xslt 中使用文档函数编写 xpath 时,转换工作得很好(请参阅示例 xslt 中的元素 PanelOK):

但是当 xPath 本身存储在变量中时,它将不起作用(参见元素 PanelException):

<xsl:value-of select="@Customer"/>

其中@Customer 的值为“document('myXml.xml')/COM:root/COM:Global/@Customer”

然后我用一个脚本扩展了我的 xslt。当我不在 xpath 中使用文档功能时,这很好用,例如仅 /COM:root/COM:Global/@Customer。但是对于文档函数,我得到了异常 XsltContext is required for this query because an unknown function.

以下是示例:xml1 具有属性 customer,其值包含 xpath 表达式,xml2 是可以找到该值的文件,xslt 是转换 xml1 并评估存储在属性 customer 中的 xpath 表达式的转换应该使用自定义脚本在 xml2 中查找值,然后在 select 语句中出现异常。我必须怎么做才能让它发挥作用?

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>

【问题讨论】:

  • 好问题,+1。请参阅我的答案以解释为什么没有扩展这是不可能的,而今天的 .NET xslt 处理器根本不可能。解决方法是可能的,如果您表示您对此感兴趣——可能会提出一个新问题并尽可能具体地定义它——我将很乐意提供这样的解决方法。
  • 首先,内联扩展函数定义不是标准的 XSLT 内容模型。其次,您正在尝试将 XSLT 函数与 XPath 引擎一起使用。除了两步转换的经典解决方案(样式表将输入源转换为新样式表以输出最终结果)和简单的遍历模板,我还建议将信息分成两部分:路径和文档,如&lt;SFK:Panel Customer="/COM:root/COM:Global/@Customer" Source="setting.xml"/&gt;.
  • 还请注意,有人努力为 XPath 评估提供 XSLT 上下文:msdn.microsoft.com/en-us/library/ms950806.aspxmsdn.microsoft.com/en-us/library/ms950808.aspx
  • @Dimitre:我对解决方法非常感兴趣。我发布了一个新问题...stackoverflow.com/questions/4922578/…

标签: xml xslt


【解决方案1】:

我担心document 函数没有在 XPath 规范中定义,因此在像 Microsoft 的 XPathNavigator 这样的 XPath 1.0 实现中不可用。 document 函数仅在 XSLT 中定义。

我不确定该建议什么,对于 Saxon 9 或 XQSharp,您可以改用 XPath 2.0 doc 函数,但我不确定您是否想摆脱 .NET 框架的内置 XSLT 和 XPath 1.0 实现到第三方 XSLT 和 XPath 2.0 实现。

【讨论】:

    【解决方案2】:

    EXSLT 函数 dyn:evaluate 未在 Microsoft XSLT 处理器中实现

    如果所需 XPath 表达式的不同部分被编码在 xml1 的单独元素/属性中,您可以解决此问题。

    当然,这是一个非常有限的解决方案,需要惯例和纪律。

    即使在 XSLT 2.0/XPath2.0 中也不支持动态评估 XPath 表达式。这种支持可能会在以后的版本中提供,但 3.0 版本仍处于“工作草案”状态。

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 2014-08-27
      • 1970-01-01
      • 2011-03-21
      相关资源
      最近更新 更多