XslCompiledTransform使用从string创建的XmlTestReader进行转换

时间:2012-12-06 11:28:20

标签: c# xslt

我遇到XslCompiledTransform类的问题。 如果我试图运行此代码:

string pathToXsltFile, pathToInputFile, pathToOutputFile;
XsltSettings xsltSettings = new XsltSettings(true, true);
XslCompiledTransform myXslTransform = new XslCompiledTransform();
XmlTextReader reader = new XmlTextReader(pathToFile);
myXslTransform.Load(reader, xsltSettings, new XmlUrlResolver());
myXslTransform.Transform(pathToInputFile, pathToOutputFile);

工作正常。 但是如果我想从字符串(文本)创建XmlTextReader:

MemoryStream mStrm = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(text));
XmlTextReader xmlReader = new XmlTextReader(mStrm);
mStrm.Position = 0;

尝试运行:

myXslTransform.Load(xmlReader, xsltSettings, new XmlUrlResolver());
myXslTransform.Transform(pathToInputFile, pathToOutputFile);

我得到一个例外:

"this operation is not supported for a relative uri"

由于某些原因,我不想创建临时文件并从路径创建XmlTextReader。

修改

完整的异常消息:

"An error occurred while loading document ''.
See InnerException for a complete description of the error."

InnerException.Message:

"This operation is not supported for a relative URI."

堆栈追踪:

at System.Xml.Xsl.Runtime.XmlQueryContext.GetDataSource(String uriRelative, String uriBase)
at <xsl:template match=\"gmgml:FeatureCollection\">(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator {urn:schemas-microsoft-com:xslt-debug}current)
at <xsl:apply-templates>(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime, XPathNavigator )
at Root(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
at Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
at System.Xml.Xsl.XmlILCommand.Execute(XmlReader contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, Stream results)
at System.Xml.Xsl.XslCompiledTransform.Transform(String inputUri, String resultsFile)
at MyNamespace.ApplyXslTransformation1(String input, String output, String xsltFileName)

导致异常的声明:

myXslTransform.Transform(pathToInputFile, pathToOutputFile);

关于文件功能我明天要问。我从另一个人那里得到了xslt文件。

当我从xslt文件的路径创建XmlTextReader文件时,每个人都很好。我也尝试使用:

myXslTransform.Load(pathToXsltFile, xsltSettings, new XmlUrlResolver());
myXslTransform.Transform(pathToInputFile, pathToOutputFile);

这也很好。

现在我得到加密的xslt。我解密了它,我想从解密的字符串创建XmlTextReader。由于安全原因,我不会创建临时的xslt解密文件。

3 个答案:

答案 0 :(得分:1)

我认为我们需要查看XSLT以及它对document函数的任何调用。通常,您需要知道the document function有第二个参数可以作为基URI来解析第一个参数产生的URI。没有传递第二个参数,例如<xsl:value-of select="document('foo.xml')"/>样式表代码本身提供了基本URI。如果从字符串加载样式表代码,该机制可能无法解析URI,就像从文件系统或HTTP URI加载的样式表一样。该问题的解决方案取决于您要加载的资源的位置以及与主输入文件的关系。如果您要从与主输入文档相同的位置加载foo.xml,那么执行document('foo.xml', /)而不是document('foo.xml')应该有效。

答案 1 :(得分:0)

我认为这是由于您将内存流的位置手动设置为0引起的;你混淆了XmlTextReader。

我尝试了上述内容,当我评论该行时,它对我来说很好。

您是否有特殊原因将其设置为0?

答案 2 :(得分:0)

假设此问题与在.Net Core应用程序中使用XslCompiledTransform有关,我找到了“相对URI不支持此操作”的答案。在网站https://github.com/dotnet/corefx/issues/31390

相关答案(由vcsjones于2018年7月26日评论)是:

“我相信您正在进行一个已知的兼容性更改。默认情况下,.NET Core不允许为XML解析外部URI,并在此处进行了记录。

如文档所述,如果您愿意,可以通过放置

来恢复旧的行为。

AppContext.SetSwitch(“ Switch.System.Xml.AllowDefaultResolver”,true); 在您的应用程序中。尝试将其放在示例程序的顶部。”

添加时

AppContext.SetSwitch("Switch.System.Xml.AllowDefaultResolver", true);

作为

的顶行
public void Configure(IApplicationBuilder app, IHostingEnvironment env)

在启动时,错误“相对URI不支持此操作”消失了。那时,发生了一个新错误,该错误用XmlReader调用Load,该错误与查找XSL文件引用的其他文件有关。然后,当我改为将文件路径传递到Load中的xsl时,一切都按预期工作。

var resolver = new XmlUrlResolver {Credentials = CredentialCache.DefaultCredentials};
var transform = new XslCompiledTransform();
transform.Load(XslPath, new XsltSettings(true, true), resolver);

var settings = new XmlWriterSettings {OmitXmlDeclaration = true};
using (var results = new StringWriter())
using(var writer = XmlWriter.Create(results, settings))
{
    using (var reader = XmlReader.Create(new StringReader(document)))
    {
        transform.Transform(reader, writer);
    }

    return results.ToString();
}

我添加此内容是希望能帮助其他尝试调试XslCompiledTransform为何会出现错误的人“相对URI不支持此操作。”在.net核心中。