4

我正在使用 Win7 并将我的 VSC# 项目设置为 .NETFramework4。然后下载 SaxonHE9-8-0-7N-setup.exe 并安装。然后将 saxon9he-api.dll 引用到 C# 项目,using Saxon.Api; 这是我的program.cs

static void Main(string[] args)
{
    var xslt = new FileInfo(Path.GetFullPath(Path.Combine(Environment.CurrentDirectory.ToString(), @"..\..\..")) + @"\TEST.xslt");
    var input = new FileInfo(Path.GetFullPath(Path.Combine(Environment.CurrentDirectory.ToString(), @"..\..\..")) + @"\TEST.xml");
    var output = new FileInfo(Path.GetFullPath(Path.Combine(Environment.CurrentDirectory.ToString(), @"..\..\..")) + @"\result.txt");

    var processor = new Processor();
    var compiler = processor.NewXsltCompiler();
    var executable = compiler.Compile(new Uri(xslt.FullName));
    var transformer = executable.Load();
    var serializer = new Serializer();

    FileStream outStream = new FileStream(output.ToString(), FileMode.Create, FileAccess.Write);
    serializer.SetOutputStream(outStream);

    using (var inputStream = input.OpenRead())
    {
        transformer.SetInputStream(inputStream, new Uri(Path.GetTempPath()));
        transformer.SetParameter(new QName("password"), new XdmAtomicValue("secret"));
        transformer.Run(serializer);
        outStream.Close();
    }
}

这是我的TEST.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="xs math map array"
    version="3.0">

  <xsl:output method="json" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="root">
    <xsl:map>
      <xsl:map-entry key="local-name()">
        <xsl:apply-templates/>
      </xsl:map-entry>
    </xsl:map>
  </xsl:template>

  <xsl:template match="items">
    <xsl:variable name="items" as="item()*">
      <xsl:apply-templates/>
    </xsl:variable>
    <xsl:sequence select="map { local-name() : array { $items }}"/>
  </xsl:template>

  <xsl:template match="item">
    <xsl:sequence select="map { 'foo' : xs:integer(foo), 'bar' : string(bar) }"/>
  </xsl:template>

</xsl:stylesheet>

在运行之前,我收到两条错误消息:

命名空间“ http://www.w3.org/1999/XSL/Transform ”中的元素“模板”具有无效的子元素“地图”

'as' 属性未声明。

运行时,我收到一条错误消息:

xsl:map-entry/@key TEST.xslt:FOTY0013 中的错误:无法在未命名模式下的 /root 的内置模板规则中将函数项写入 XML 树**

那么我应该怎么做才能没有错误地运行这段代码呢?

4

3 回答 3

6

改行创建Transformer创建Xslt30Transformer

        var transformer = executable.Load30();

使用 XSLT 3 及其各种不同且更灵活的输入和输出选项,然后运行样式表使用

        using (var inputStream = input.OpenRead())
        {
            transformer.ApplyTemplates(inputStream, serializer);
            outStream.Close();
        }

这样,我之前发布的 XSLT 代码和您用作示例的 XSLT 代码运行良好(我必须调整文件路径,但这显然取决于文件与 C# 项目相关的方式/位置)。

请注意,通常使用 XSLT 3,初始匹配选择和用于初始化全局变量的全局上下文项可能不同,示例样式表没有任何全局变量或参数,但如果有它们,您还需要设置 GlobalContextItem ( https://www.saxonica.com/html/documentation/dotnetdoc/Saxon/Api/Xslt30Transformer.html#GlobalContextItem)到 XdmValue。

至于您在 Visual Studio 中编辑 XSLT 3 时收到的各种编辑器警告或错误消息,那么,简单地在系统上安装 XSLT 3 处理器不会将 VS 转换为 XSLT 3 编辑器,您需要检查是否/如何可以设置 Visual Studio 以使用 XSLT 3 模式,XSLT 3 规范在https://www.w3.org/TR/xslt-30/schema-for-xslt30.xsd有一个链接,但我认为它使用模式语言1.1,而 Microsoft 仅支持模式语言版本 1.0,因此可能有点难以找到和安装 VS 的模式,使其能够识别并支持 XSLT 3 编辑。

于 2018-01-02T08:31:56.153 回答
0

因为我在将此解决方案转换为 HE-9.9 时遇到问题,所以这是我的解决方案 - 需要注意的是它适用于 9.9 而不适用于 9.8:

using System;
using System.IO;
using Saxon.Api;

namespace Project1
{
    public static class ClassMain
    {
        public static string TransformXml(string xmlData, string xslData)
        {
            var xsltProcessor = new Processor();
            var documentBuilder = xsltProcessor.NewDocumentBuilder();
            documentBuilder.BaseUri = new Uri("file://");
            var xdmNode = documentBuilder.Build(new StringReader(xmlData));

            var xsltCompiler = xsltProcessor.NewXsltCompiler();
            var xsltExecutable = xsltCompiler.Compile(new StringReader(xslData));
            var xsltTransformer = xsltExecutable.Load();
            xsltTransformer.InitialContextNode = xdmNode;

            var results = new XdmDestination();

            xsltTransformer.Run(results);
            return results.XdmNode.OuterXml;
        }

        public static void Main()
        {
            var xmlData = File.ReadAllText("a.xml");
            var xslData = File.ReadAllText("a.xsl");

            var data = TransformXml(xmlData, xslData);
            Console.WriteLine(data);
            Console.ReadKey();
        }
    }
}
于 2019-11-05T07:33:11.343 回答
0

9.9 使用var serializer = processor.NewSerializer();

于 2020-05-13T14:21:46.357 回答