4

I'd like to use embedded resources in my XSLT file, but while invoking 'document(...)' C# complains that "Error during loading document ..."

I'd like to use defined resources in XSLT file and get them by this: "document('')//my:resources/"...

How can i do that??

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>

How can i get access to such structure without exceptions in C#? I'll add that during static transform via ex. Opera everything works fine.

0

2 Answers 2

12
<xsl:variable name="res" select="document('')/*/my:resources/("/>

The value of the select attribute is not a syntactically correct XPath expression. Every compliant XSLT processor must raise an error.

Solution:

Correct the above to:

<xsl:variable name="vRes" select="document('')/*/my:resources"/>

If there is still an exception raised, do read about the XsltSettings class.

Then create an instance of XsltSettings with this constructor, like this:

XsltSettings(true, false)

Do not enable scripting -- keep the second argument of the constructor as false.

Below is a more complete code snippet:

// 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());

Update: Another possible reason for an error is when the XSLT stylesheet is dynamically created in memory (doesn't come from file). In this case an XSLT processor typically cannot resolve the relative uri in document('').

In this last case the solution is to make the wanted element the content of an xsl:variable and to use the xxx:node-set() extension function to address this element.

Sign up to request clarification or add additional context in comments.

8 Comments

+1 Very good answer. Some times, when document('') gives me problems, I use p/2 function (knowing that input an stylesheet come from the same directory)
@Simon: the +1 was forgotten it seems ;). I'll add one, it's a good answer.
I am having the same problem but I don't see the answer to the question. What is p/2 function? How do you use Node-set() as a variable lookup?
ASP.Net Core needs the following in Startup.cs : public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // override XmlException: Resolving of external URIs was prohibited. AppContext.SetSwitch("Switch.System.Xml.AllowDefaultResolver", true);
@Dimitre Novatchev - Yeah, I know it is an old post, but hey, I found it... :-) Thank you for your answer.
|
0

After tearing my hair out for an entire day and a half, I finally figured out the solution to an identical issue I was seeing.

My code:

NUnit Test:

[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>

Document.xml :

<?xml version="1.0" encoding="utf-8" ?>
<Message>Document Message</Message>

Eventually I found this:

https://github.com/dotnet/runtime/issues/26969

Informing me that I needed to use a new .Net Core "Feature" which would allow me to use my external xml document, using the snippet:

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

Final code that works:

[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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.