我正在使用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”中的元素“模板”具有无效的子元素“map”
和
未声明'as'属性。
运行时收到一条错误消息:
xsl:map-entry / @ key中的错误TEST.xslt:FOTY0013:无法在未命名模式下的/ root的内置模板规则中将函数项写入XML树**
那么我应该怎么做才能运行这段代码而没有错误?
答案 0 :(得分:5)
更改线条以创建变形金刚以创建Xslt30Transformer
let merkleTree = [1,2,3,4,5,6,7,8,9]
let numberOfDivisions = Int(log2(Double(merkleTree.count))) + 1
let startValue = merkleTree.count
let nSizes = (0..<numberOfDivisions).reduce([startValue]) { (result, next) -> [Int] in
var newResult = result
newResult.append((result.last! + 1) / 2)
return newResult
}
print(nSizes)
// and now you can for-in it:
for nSize in nSizes {
// ...
}
使用XSLT 3及其各种不同且更灵活的输入和输出选项,然后运行样式表使用
var transformer = executable.Load30();
这样我之前发布的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编辑。
答案 1 :(得分: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();
}
}
}
答案 2 :(得分:0)
对于9.9使用var serializer = processor.NewSerializer();