如何在 .NET 中使用 Saxon-HE 9.8 使用 XSLT 3.0 [英] How to use XSLT 3.0 using Saxon-HE 9.8 in .NET

查看:147
本文介绍了如何在 .NET 中使用 Saxon-HE 9.8 使用 XSLT 3.0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using Win7 and set my VSC# project to .NETFramework4. Then download SaxonHE9-8-0-7N-setup.exe and install. Then reference saxon9he-api.dll to C# project and using Saxon.Api; And here's my 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>

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

Before runing I receive two error message:

命名空间 'http://www.w3.org/1999 中的元素 'template'/XSL/Transform' 具有无效的子元素 'map'

The element 'template' in namespace 'http://www.w3.org/1999/XSL/Transform' has invalid child element 'map'

未声明as"属性.

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

When running I receive one error message:

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

Error in xsl:map-entry/@key TEST.xslt:FOTY0013: Cannot write a function item to an XML tree in built-in template rule for /root in the unnamed mode**

那么我应该怎么做才能正确运行这段代码?

So what should I do to run this code without error?

推荐答案

更改行以创建 Transformer 以创建 Xslt30Transformer

Change the line to create a Transformer to create an Xslt30Transformer

        var transformer = executable.Load30();

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

to use XSLT 3 and its various, different and more flexible input and output options and then to run the stylesheet use

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

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

That way the XSLT code I posted earlier and you used as an example runs fine (I had to adapt the file paths but that obviously depends on how/where the files are in relation to the C# project).

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

Note that in general with XSLT 3 the initial match selection and the global context item to initialize global variables can be different, the sample stylesheet does not have any global variables or parameters, but if it had them you would also need to set the GlobalContextItem (https://www.saxonica.com/html/documentation/dotnetdoc/Saxon/Api/Xslt30Transformer.html#GlobalContextItem) to an 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 而微软只支持模式语言版本 1.0,因此为 VS 找到并安装使其识别和支持 XSLT 3 编辑的架构可能有点困难.

As for the various editor warnings or error messages you get when editing XSLT 3 in Visual Studio, well, simply installing an XSLT 3 processor on your system does not convert VS into an XSLT 3 editor, you will need to check whether/how you can set up Visual Studio to use the XSLT 3 schema, the XSLT 3 spec has one linked at https://www.w3.org/TR/xslt-30/schema-for-xslt30.xsd but I think it uses the schema language 1.1 while Microsoft only supports the schema language version 1.0 so it might be a bit difficult to find and install a schema for VS that makes it recognize and support XSLT 3 editing.

这篇关于如何在 .NET 中使用 Saxon-HE 9.8 使用 XSLT 3.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆