加载XML和XSLT从撒克逊9.4he嵌入资源 [英] Load xml and xslt from embedded resource in Saxon 9.4he
问题描述
我使用撒克逊9.4家庭版(撒克逊-HE 9.4 .NET )来获得对于XSLT 2.0和XPath 2.0和XQuery 1.0 .NET的支持。我的代码崩溃时我加载文件,而一个URI。
- 是否有可能加载XML / XSL文档,而不涉及到加载的文档的URI ?
- 如果没有,有没有办法来定义的URI嵌入的dll文件的元素?
任何其它解决方案也将被理解的是,我的唯一的术语是该文件必须从DLL文件内被加载
只要我的代码工作完全如我加载XML / XSL文件来自:
常量字符串SOURCEPATH = @C:\test\TestInvoiceWithError.xml
常量字符串xsltpath = @C:\test\UBL-T10-BiiRules.xsl
当我尝试从嵌入的资源加载代码抛出一个异常,说明的没有基本URI提供的的:
流的SourceStream = GetEmbeddedResource(TestProject1.testfiles.TestInvoice.xml);
流xsltStream = GetEmbeddedResource(TestProject1.testfiles.UBL-T10-BiiRules.xsl);
我也创建乌里对与抛出异常的相对路径资源的'这个操作不支持相对URI的:
乌里sourceUri =新的URI(/ TestProject1;组件/ testfiles /TestInvoice.xml,UriKind.Relative);
乌里xsltUri =新的URI(/ TestProject1;组件/ testfiles / UBL-T10-BiiRules.xsl.xml,UriKind.Relative);
下面是我的代码:
使用系统;
使用System.Collections.Generic;
:使用System.IO;
使用的System.Reflection;
使用System.Text;
使用的System.Xml;
使用Microsoft.VisualStudio.TestTools.UnitTesting;
使用Saxon.Api;
命名空间TestProject1
{
[TestClass中]
公共类XsltTest
{
[TestMethod的]
公无效SaxonTest()
{
流的SourceStream = GetEmbeddedResource(TestProject1.testfiles.TestInvoice.xml);
流xsltStream = GetEmbeddedResource(TestProject1.testfiles.UBL-T10-BiiRules.xsl);
乌里sourceUri =新的URI(/ TestProject1;组件/ testfiles / TestInvoice.xml,UriKind.Relative);
乌里xsltUri =新的URI(/ TestProject1;组件/ testfiles / UBL-T10-BiiRules.xsl.xml,UriKind.Relative);
常量字符串SOURCEPATH = @C:\test\TestInvoiceWithError.xml
常量字符串xsltpath = @C:\test\UBL-T10-BiiRules.xsl
处理器处理器=新处理器();
XdmNode输入= processor.NewDocumentBuilder()构建(新的URI(SOURCEPATH))。
XsltTransformer变压器= processor.NewXsltCompiler()编译(新的URI(xsltpath))负载()。
transformer.InitialContextNode =输入;
串行串行=新的串行();
StringBuilder的SB =新的StringBuilder();
TextWriter的作家=新的StringWriter(某人);
serializer.SetOutputWriter(作家);
transformer.Run(串行);
XmlDocument的xmlDocOut =新的XmlDocument();
xmlDocOut.LoadXml(sb.ToString());
XmlNodeList中failedAsserts = xmlDocOut.SelectNodes(/ svrl:Schematron的输出/ svrl:失败断言,XmlInvoiceNamespaceManager());
如果(failedAsserts == NULL)
的回报;
的foreach(XmlNode的failedAssert在failedAsserts)
{
如果(failedAssert.Attributes == NULL)
继续;
XmlAttribute typeOfError = failedAssert.Attributes [标志];
如果(typeOfError.Value.Equals(警告))
{/ *登录的东西* /}
,否则如果(typeOfError.Value.Equals(致命) )
{/ *登录的东西* /}
}
}
私人的XmlNamespaceManager XmlInvoiceNamespaceManager()
{
的IDictionary<字符串,字符串> ;名单=新词典<字符串,字符串>
{
{XML,http://www.w3.org/XML/1998/namespace},
{XSI,HTTP://www.w3 .ORG / 2001 / XML模式实例},
{XSD,http://www.w3.org/2001/XMLSchema},
{UDT,金塔:UN :联合国欧洲经济委员会:uncefact:数据:规格:UnqualifiedDataTypesSchemaModule:2}
{QDT,金塔:绿洲:名称:规格:UBL:架构:XSD:QualifiedDatatypes-2}
{ 内线,金塔:绿洲:名称:规格:UBL:架构:XSD:CommonExtensionComponents-2}
{有条件现金转移支付,金塔:联合国:联合国欧洲经济委员会:uncefact:文档:2}
{CBC,金塔:绿洲:名称:规格:UBL:架构:XSD:CommonBasicComponents-2}
{CAC,金塔:绿洲:名称:规格:UBL:架构:XSD:CommonAggregateComponents-2}
{INV,金塔:绿洲:名称:规格:UBL:架构:XSD:发票-2}
{svrl,HTTP ://purl.oclc.org/dsdl/svrl}
};
XmlNameTable xmlNameTable =新NameTable();
的XmlNamespaceManager xmlInvoiceNamespaceManager =新的XmlNamespaceManager(xmlNameTable);
的foreach(KeyValuePair<字符串,字符串>在列表NS)
{
xmlInvoiceNamespaceManager.AddNamespace(ns.Key,ns.Value);
}
返回xmlInvoiceNamespaceManager;
}
受保护的静态流GetEmbeddedResource(字符串路径)
{
ASM大会= Assembly.GetExecutingAssembly();
流流= asm.GetManifestResourceStream(路径);
返回流;
}
}
}
我认为你可以从撒克逊流负载,但你需要设置基本URI第一,允许加载任何引用的资源(如DTD XML文档或类似包含或导入的样式表模块)。如果你确信你没有那个那么简单地尝试例如
的DocumentBuilder DB = processor.NewDocumentBuilder();
db.BaseUri =新的URI(文件:/// C:/);
XdmNode输入= db.Build(xsltStream);
显然,如果你需要,同时也是对XSLT来解析相对URI被加载嵌入的资源更多工作是需要:需要建立的XmlResolver
来,在XSLT与URI的方案支持从嵌入的资源加载资源,一起一类以指示解析器,你需要从资源加载。我不认为.NET框架提供了这样一种的XmlResolver和Uri类不支持的自定义架构无论是。
I am using Saxon 9.4 home edition (Saxon-HE 9.4 .NET) to get support for XSLT 2.0 and XPath 2.0, and XQuery 1.0 in .NET. My code crashes when I load files without an URI.
- Is it possible to load xml/xsl documents without an URI related to the document loaded?
- If not, is there any way to define URI for elements embedded in dll-files?
Any other solutions will also be appreciated, my only term is that the files must be loaded from within the dll-file.
My code works perfectly as long as i load xml/xsl from file:
const string sourcePath = @"C:\test\TestInvoiceWithError.xml";
const string xsltpath = @"C:\test\UBL-T10-BiiRules.xsl";
When i try to load from embedded resource the code throws an exception stating 'No base URI supplied':
Stream sourceStream = GetEmbeddedResource("TestProject1.testfiles.TestInvoice.xml");
Stream xsltStream = GetEmbeddedResource("TestProject1.testfiles.UBL-T10-BiiRules.xsl");
I have also created Uri's for resources with relative path which throws the exception 'This operation is not supported for a relative URI.':
Uri sourceUri = new Uri("/TestProject1;component/testfiles/TestInvoice.xml", UriKind.Relative);
Uri xsltUri = new Uri("/TestProject1;component/testfiles/UBL-T10-BiiRules.xsl.xml", UriKind.Relative);
Here is my code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Saxon.Api;
namespace TestProject1
{
[TestClass]
public class XsltTest
{
[TestMethod]
public void SaxonTest()
{
Stream sourceStream = GetEmbeddedResource("TestProject1.testfiles.TestInvoice.xml");
Stream xsltStream = GetEmbeddedResource("TestProject1.testfiles.UBL-T10-BiiRules.xsl");
Uri sourceUri = new Uri("/TestProject1;component/testfiles/TestInvoice.xml", UriKind.Relative);
Uri xsltUri = new Uri("/TestProject1;component/testfiles/UBL-T10-BiiRules.xsl.xml", UriKind.Relative);
const string sourcePath = @"C:\test\TestInvoiceWithError.xml";
const string xsltpath = @"C:\test\UBL-T10-BiiRules.xsl";
Processor processor = new Processor();
XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourcePath));
XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(xsltpath)).Load();
transformer.InitialContextNode = input;
Serializer serializer = new Serializer();
StringBuilder sb = new StringBuilder();
TextWriter writer = new StringWriter(sb);
serializer.SetOutputWriter(writer);
transformer.Run(serializer);
XmlDocument xmlDocOut = new XmlDocument();
xmlDocOut.LoadXml(sb.ToString());
XmlNodeList failedAsserts = xmlDocOut.SelectNodes("/svrl:schematron-output/svrl:failed-assert",XmlInvoiceNamespaceManager());
if (failedAsserts == null)
return;
foreach (XmlNode failedAssert in failedAsserts)
{
if (failedAssert.Attributes == null)
continue;
XmlAttribute typeOfError = failedAssert.Attributes["flag"];
if (typeOfError.Value.Equals("warning"))
{/*Log something*/}
else if (typeOfError.Value.Equals("fatal"))
{/*Log something*/}
}
}
private XmlNamespaceManager XmlInvoiceNamespaceManager()
{
IDictionary<string, string> list = new Dictionary<string, string>
{
{"xml", "http://www.w3.org/XML/1998/namespace"},
{"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
{"xsd", "http://www.w3.org/2001/XMLSchema"},
{"udt","urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"},
{"qdt","urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"},
{"ext","urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"},
{"ccts", "urn:un:unece:uncefact:documentation:2"},
{"cbc","urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"},
{"cac","urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"},
{"inv", "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"},
{"svrl", "http://purl.oclc.org/dsdl/svrl"}
};
XmlNameTable xmlNameTable = new NameTable();
XmlNamespaceManager xmlInvoiceNamespaceManager = new XmlNamespaceManager(xmlNameTable);
foreach (KeyValuePair<string, string> ns in list)
{
xmlInvoiceNamespaceManager.AddNamespace(ns.Key, ns.Value);
}
return xmlInvoiceNamespaceManager;
}
protected static Stream GetEmbeddedResource(string path)
{
Assembly asm = Assembly.GetExecutingAssembly();
Stream stream = asm.GetManifestResourceStream(path);
return stream;
}
}
}
I think you can load from a stream with Saxon but you need to set a base URI first that would allow to load any references resources (like a DTD in an XML document or like included or imported stylesheet modules). If you are sure you don't have that then simply try e.g.
DocumentBuilder db = processor.NewDocumentBuilder();
db.BaseUri = new Uri("file:///C:/");
XdmNode input = db.Build(xsltStream);
Obviously if you need to resolve relative URIs in the XSLT that are also to be loaded as embedded resource more work is needed: you need to set up the XmlResolver
to a class that supports loading the resource from an embedded resource, together with a scheme of URIs in the XSLT to indicate to the resolver that you need to load from a resource. I don't think the .NET framework provides such a kind of XmlResolver and the Uri class does not support a custom schema for that either.
这篇关于加载XML和XSLT从撒克逊9.4he嵌入资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!