0
votes

I have some problems when I want transform an xml datas. I using XslCompiledTransform object on .Net framework 4.0.

XDocument v_xdoc = XDocument.Load("XLMData.xml");
XslCompiledTransform myXslTrans = new XslCompiledTransform();
myXslTrans.Load("XSLTFile1.xslt", new XsltSettings(true, false), null);
XPathNavigator nav = v_xdoc.CreateNavigator();

using (TextWriter myWriter = File.CreateText("result.scpt"))
{
    myXslTrans.Transform(nav, null, myWriter);
}

I have this crash:

For safety reasons, in this document prohibited DTD XML. To enable DTD processing set on Parse the property on XmlReaderSettings DtdProcessing and pass parameters to the method XmlReader.Create.

When I change my code with XmlReaderSettings :

XDocument v_xdoc = XDocument.Load("XLMData.xml");

XslCompiledTransform myXslTrans = new XslCompiledTransform(true);
myXslTrans.Load(
    XmlReader.Create("XSLTFile1.xslt", 
    new XmlReaderSettings()
    {
        DtdProcessing = DtdProcessing.Parse
    }),
    new XsltSettings(true, false),
    null
);

XPathNavigator nav = v_xdoc.CreateNavigator();
using (TextWriter myWriter = File.CreateText("result.scpt"))
{
    myXslTrans.Transform(nav, null, myWriter);
}

I have the same crash.

This is my XsltFile

<?xml version="1.0"?>

<!DOCTYPE xsl:stylesheet [
  <!ENTITY nbsp "&#x00A0;">
  <!ENTITY euro "&#8364;" >
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:csv="csv:csv"
                xmlns:n="http://novamap.fr/xml/data/v1"
                version="1.0">

  <xsl:output method="text" encoding="utf-8"/>

  <xsl:variable name="delimiter" select="';'"/>

  <csv:columns>
    <column>BDC_ID_BON_DE_COMMANDE</column>
    <column>BDC_LI_BON_DE_COMMANDE</column>
    <column>BDC_REF_BON_DE_COMMANDE</column>
    <column>BDC_DT_EMISSION_STR</column>
  </csv:columns>

  <xsl:template match="/n:XmlModelBonDeCommande">

    <xsl:for-each select="document('')/*/csv:columns/*">
      <xsl:value-of select="."/>
      <xsl:if test="position() != last()">
        <xsl:value-of select="$delimiter"/>
      </xsl:if>
    </xsl:for-each>

    <xsl:text>
</xsl:text>
    <!-- Output rows for each matched property -->
    <xsl:apply-templates select="n:GMP_BON_DE_COMMANDE"/>
  </xsl:template>

</xsl:stylesheet>

This is my XmlFile

<XmlModelBonDeCommande xmlns="http://novamap.fr/xml/data/v1">
  <GMP_BON_DE_COMMANDE>
    <BDC_ID_BON_DE_COMMANDE>154</BDC_ID_BON_DE_COMMANDE>
    <BDC_LI_BON_DE_COMMANDE>BON DE COMMANDE</BDC_LI_BON_DE_COMMANDE>
    <BDC_REF_BON_DE_COMMANDE>20140624-08</BDC_REF_BON_DE_COMMANDE>
    <BDC_DT_EMISSION>2014-06-24T02:00:00+02:00</BDC_DT_EMISSION>
    <BDC_DT_EMISSION_STR>24/06/2014</BDC_DT_EMISSION_STR>
    <BDC_MT_MONTANT_HT>132.38</BDC_MT_MONTANT_HT>
    <BDC_MT_MONTANT_HT_STR>132,38</BDC_MT_MONTANT_HT_STR>
    <BDC_MT_MONTANT_TVA>9.27</BDC_MT_MONTANT_TVA>
    <BDC_MT_MONTANT_TVA_STR>9,27</BDC_MT_MONTANT_TVA_STR>
    <BDC_MT_MONTANT_TTC>141.65</BDC_MT_MONTANT_TTC>
    <BDC_MT_MONTANT_TTC_STR>141,65</BDC_MT_MONTANT_TTC_STR>
  </GMP_BON_DE_COMMANDE>
</XmlModelBonDeCommande>

The execution trace :

'WindowsFormsApplication4.vshost.exe' (Managé (v4.0.30319)) : 'c:\users\dell\documents\visual studio 2012\Projects\WindowsFormsApplication4\WindowsFormsApplication4\bin\Debug\WindowsFormsApplication4.exe' chargé, symboles chargés.
'WindowsFormsApplication4.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.SqlXml\v4.0_4.0.0.0__b77a5c561934e089\System.Data.SqlXml.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
'WindowsFormsApplication4.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll' chargé, chargement des symboles ignoré. Le module est optimisé et l'option du débogueur 'Uniquement mon code' est activée.
'WindowsFormsApplication4.vshost.exe' (Managé (v4.0.30319)) : 'System.Xml.Xsl.CompiledQuery.1' chargé
'WindowsFormsApplication4.vshost.exe' (Managé (v4.0.30319)) : 'System.Xml.Xsl.CompiledQuery.2' chargé
'WindowsFormsApplication4.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_32\ISymWrapper\v4.0_4.0.0.0__b03f5f7f11d50a3a\ISymWrapper.dll' chargé
'WindowsFormsApplication4.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml.resources\v4.0_4.0.0.0_fr_b77a5c561934e089\System.Xml.resources.dll' chargé
'WindowsFormsApplication4.vshost.exe' (Managé (v4.0.30319)) : 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.SqlXml.resources\v4.0_4.0.0.0_fr_b77a5c561934e089\System.Data.SqlXml.resources.dll' chargé
Une exception de première chance de type 'System.Xml.Xsl.XslTransformException' s'est produite dans System.Data.SqlXml.dll

and message exception :

Pour des raisons de sécurité, DTD interdite dans ce document XML. Pour activer le traitement DTD, définissez sur Parse la propriété DtdProcessing sur XmlReaderSettings et transmettez les paramètres à la méthode XmlReader.Create.

When i remove the DOCTYPE it work fine but i need it. I don't find the good arguments for load my xslt file. Someone have an idea ?

1
The exception text seems "off". That's not the original English-language exception, is it? And do you really get exactly the same exception when you use DtdProcessing.Parse as when you have the default value of DtdProcessing.Prohibit (which is what the exception text you posted seems to go with)? - Peter Duniho
@PeterDuniho The text is a traduction from french language. But with DtdProcessing.Prohibit has same crash. - tdelepine
Fine, so now we know that your XSLT stylesheet use document('') to read in the XSLT itself and it seems that this causes the error. It looks as if Visual Studio can run and debug your XML and stylesheet without causing that exception but I am currently not sure how to change the C# code to avoid the exception. There are however ways to change the XSLT to avoid using a DOCTYPE to simply create some entities that could as well be directly presented as characters in XML and Unicode. I could also make a suggestion as to rewrite the XSLT to avoid using the document(''). - Martin Honnen
I rewrote my answer to show how to avoid the use of document(''). Perhaps that is an option for you. - Martin Honnen
It's great that you found Martin's answer helpful in fixing your problem. For future reference: the text you posted is not a stack trace. It's just the run-time output from the program; all it tells us are a bunch DLLs that goes loaded, and then that the XslTransformException was thrown by System.Data.SqlXml.dll. Most critically, it does not tell us which line of your code called SqlXml.dll, nor what method in that DLL was called. If Martin hadn't been able to guess the actual problem, a real stack trace would have been very useful. - Peter Duniho

1 Answers

0
votes

It seems the use of document('') in your XSLT is causing the exception.

You could avoid that use with a change like

<?xml version="1.0"?>

<!DOCTYPE xsl:stylesheet [
  <!ENTITY nbsp "&#x00A0;">
  <!ENTITY euro "&#8364;" >
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:exsl="http://exslt.org/common"
                xmlns:csv="csv:csv"
                xmlns:n="http://novamap.fr/xml/data/v1"
                version="1.0">

  <xsl:output method="text" encoding="utf-8"/>

  <xsl:variable name="delimiter" select="';'"/>

  <xsl:variable name="columns">
  <csv:columns>
    <column>BDC_ID_BON_DE_COMMANDE</column>
    <column>BDC_LI_BON_DE_COMMANDE</column>
    <column>BDC_REF_BON_DE_COMMANDE</column>
    <column>BDC_DT_EMISSION_STR</column>
  </csv:columns>
  </xsl:variable>

  <xsl:template match="/n:XmlModelBonDeCommande">

    <xsl:for-each select="exsl:node-set($columns)/csv:columns/*">
      <xsl:value-of select="."/>
      <xsl:if test="position() != last()">
        <xsl:value-of select="$delimiter"/>
      </xsl:if>
    </xsl:for-each>

    <xsl:text>
</xsl:text>
    <!-- Output rows for each matched property -->
    <xsl:apply-templates select="n:GMP_BON_DE_COMMANDE"/>
  </xsl:template>

</xsl:stylesheet>