在 .NET XSLT 中使用 document() 函数会产生错误
Posted
技术标签:
【中文标题】在 .NET XSLT 中使用 document() 函数会产生错误【英文标题】:using document() function in .NET XSLT generates error 【发布时间】:2021-04-26 01:58:34 【问题描述】:我想在我的 XSLT 文件中使用嵌入式资源,但是在调用 'document(...)' C# 时抱怨“加载文档时出错 ...”
我想使用 XSLT 文件中定义的资源并通过以下方式获取它们:“document('')//my:resources/”...
我该怎么做??
ex xsl:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="xslt-gruper-v1.2.xsl" exclude-result-prefixes="my">
<my:resources>
<one>tryb</one>
</my:resources>
<xsl:variable name="res" select="document('')/*/my:resources/("/>
</xsl:stylesheet>
如何在 C# 中无异常地访问此类结构?我将在通过 ex 进行静态转换期间添加它。 Opera 一切正常。
【问题讨论】:
【参考方案1】:<xsl:variable name="res" select="document('')/*/my:resources/("/>
select
属性的值不是语法正确的 XPath 表达式。每个兼容的 XSLT 处理器都必须引发错误。
解决方案:
将上述更正为:
<xsl:variable name="vRes" select="document('')/*/my:resources"/>
如果仍然引发异常,请阅读XsltSettings 类。
然后使用this constructor 创建一个 XsltSettings 实例,如下所示:
XsltSettings(true, false)
不启用脚本 -- 保持构造函数的第二个参数为false
。
下面是更完整的代码sn-p:
// Create the XsltSettings object with document() enabled and script disabled.
XsltSettings settings = new XsltSettings(true,false);
// Create the XslCompiledTransform object and load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("sort.xsl", settings, new XmlUrlResolver());
更新:另一个可能的错误原因是 XSLT 样式表是在内存中动态创建的(不是来自文件)。在这种情况下,XSLT 处理器通常无法解析 document('')
中的相对 uri。
在最后一种情况下,解决方案是将所需元素设为 xsl:variable
的内容,并使用 xxx:node-set()
扩展函数来处理此元素。
【讨论】:
+1 非常好的答案。有时,当document('')
给我带来问题时,我使用 p/2 函数(知道输入的样式表来自同一目录)
@Simon:+1 似乎被遗忘了;)。我会加一个,这是一个很好的答案。
我遇到了同样的问题,但我没有看到问题的答案。什么是 p/2 函数?如何使用 Node-set() 作为变量查找?
@goroth node-set() 选择作为变量值的临时树——更准确地说,将作为变量值的 RTF(结果树片段)转换为可以操作的普通XPath文档节点。
@DimitreNovaatchev 感谢您提供的信息。我有类似的问题,但有人能够帮助我。 ***.com/questions/27365166/…【参考方案2】:
在扯了一天半的头发之后,我终于找到了解决我所看到的相同问题的方法。
我的代码:
NUnit 测试:
[Test]
public void Transform_WhenXslUsesTheDocumentFunction_DoesNotThrow()
//Arrange
string testOutputPath = GetTestOutputPath(
nameof(Transform_WhenXslUsesTheDocumentFunction_DoesNotThrow)
);
string inputXsl = TestFilePaths.GetResource("Import\\DocumentImporter.xsl");
XsltSettings xsltSettings = new XsltSettings(true, true);
XmlUrlResolver resolver = new XmlUrlResolver();
XslCompiledTransform xslCompiledTransform = new XslCompiledTransform();
xslCompiledTransform.Load(inputXsl, xsltSettings, resolver);
//Act
TestDelegate testDelegate = () => xslCompiledTransform.Transform(
TestFilePaths.MinimumValidXml
, testOutputPath
);
//Assert
Assert.DoesNotThrow(testDelegate);
DocumentImporter.xsl:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:variable name="DocumentPath" select="'./Document.xml'"/>
<xsl:variable name="DocumentXML" select="document($DocumentPath)"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:value-of select="$DocumentXML//Message"/>
</xsl:template>
</xsl:stylesheet>
文档.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Message>Document Message</Message>
最终我发现了这个:
https://github.com/dotnet/runtime/issues/26969
通知我我需要使用新的 .Net Core“功能”,这将允许我使用我的外部 xml 文档,使用 sn-p:
AppContext.SetSwitch("Switch.System.Xml.AllowDefaultResolver", true);
工作的最终代码:
[Test]
public void Transform_WhenXslUsesTheDocumentFunction_DoesNotThrow()
AppContext.SetSwitch("Switch.System.Xml.AllowDefaultResolver", true);
//Arrange
string testOutputPath = GetTestOutputPath(
nameof(Transform_WhenXslUsesTheDocumentFunction_DoesNotThrow)
);
string inputXsl = TestFilePaths.GetResource("Import\\DocumentImporter.xsl");
XsltSettings xsltSettings = new XsltSettings(true, true);
XmlUrlResolver resolver = new XmlUrlResolver();
XslCompiledTransform xslCompiledTransform = new XslCompiledTransform();
xslCompiledTransform.Load(inputXsl, xsltSettings, resolver);
//Act
TestDelegate testDelegate = () => xslCompiledTransform.Transform(
TestFilePaths.MinimumValidXml
, testOutputPath
);
//Assert
Assert.DoesNotThrow(testDelegate);
【讨论】:
以上是关于在 .NET XSLT 中使用 document() 函数会产生错误的主要内容,如果未能解决你的问题,请参考以下文章
XML - XSLT - count() 函数内的 document() 函数
在 WebLogic 中使用相对路径调用 xslt document() 函数