【问题标题】:using document() function in .NET XSLT generates error在 .NET XSLT 中使用 document() 函数会产生错误
【发布时间】: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 一切正常。

【问题讨论】:

    标签: c# xml xslt


    【解决方案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 感谢您提供的信息。我有类似的问题,但有人能够帮助我。 stackoverflow.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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 2020-07-23
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      相关资源
      最近更新 更多