在 msxml 中实现 evaluate(XPath)

implementing evaluate(XPath) in msxml

我正在编写一个实验,其中我使用一个 XML 文件,其中嵌入了 XPaths,并尝试针对另一个包含数据的 XML 文件来处理它,其中 XPaths引用数据中某些预定义节点集中的元素....基本上将视图绑定到数据列表。

我基本上已经开始工作了,除了如何评估 XPaths 本身,显然我可以在 saxon 3.0 中做到这一点(也许我应该先在那里尝试),但如果这在 msxml 中工作一开始会很方便.我读过有关“扩展”和嵌入的内容 javascript...但我真的看不出它是如何工作的(它对我不起作用)。

有什么想法吗?

(我可以让 xslt 创建一个创建输出的 xslt,但这是一个粗略的现成的概念证明,这可能会让我头疼)。

如果有必要,我可以创建一个明确的示例,但我的实际情况非常复杂。

在 .NET 中 XPathNavigator 有一个 Evaluate 方法:https://docs.microsoft.com/en-us/dotnet/api/system.xml.xpath.xpathnavigator.evaluate?view=netcore-3.1. You can expose it from an extension object 到 XslCompiledTransform。

Mvp.Xml 库这样做是为了将命名空间 xmlns:dyn2="http://gotdotnet.com/exslt/dynamic" 中的 dyn2:evaluate 扩展函数暴露给它的包装器 MvpXslTransform class XslCompiledTransform ].

该库在 NuGet 上以 .NET 标准 2.0 兼容(即 .NET 框架和 .NET Core 兼容)包的形式提供:https://www.nuget.org/packages/Mvp.Xml.NetStandard.

最简单的代码是 (using Mvp.Xml.Common.Xsl;):

        var processor = new MvpXslTransform();

        processor.SupportedFunctions = Mvp.Xml.Exslt.ExsltFunctionNamespace.GdnDynamic;

        processor.Load("XSLTFile1.xslt");

        processor.Transform(new XmlInput("XMLFile1.xml"), null, new XmlOutput(Console.Out));

样式表使用的地方,例如dyn2:evaluate(., path)xmlns:dyn2="http://gotdotnet.com/exslt/dynamic",其中上下文节点的 path 子元素包含 XPath 表达式。

源代码位于https://github.com/keimpema/Mvp.Xml.NetStandard/blob/master/library/Mvp.Xml/Exslt/GDNDynamic.cs

在 .NET 框架中,您还可以将 .NET 代码直接嵌入到 XSLT 中,XslCompiledTransform 将使用适当的 XsltSettings (new XsltSettings() { EnableScript = true } 编译并 运行 它):

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:my-ext="http://example.com/my-ext"
   exclude-result-prefixes="msxsl my-ext">

  <msxsl:script implements-prefix="my-ext" language="C#">
    public object evaluate(XPathNodeIterator context, string expression)
    {
    if (context.MoveNext()) {
      return context.Current.Evaluate(expression);
    }
    else {
      return null;
    }
    }
  </msxsl:script>

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="xpath-test">
    <xsl:copy>
      <result>
        <xsl:value-of select="my-ext:evaluate(., path)"/>
      </result>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

我不知道 Visual Studio 是否允许您为其转换菜单启用该设置。