locked
"DTD prohibited" when calling XslCompiledTransform.Transform()

    Question

  • I am using XSLT to convert a HTML file to XSL-FO.  The code is shown below.

    1// Load the FO style sheet. 
    2XslCompiledTransform xslt = new XslCompiledTransform(); 
    3xslt.Load(@"PDF\xhtml-to-xslfo.xsl"); 
    4 
    5// Execute the transform and output the results to a file. 
    6xslt.Transform(htmlFilePath, foFilePath); 
    7 

    At line 6, I get an exception:

    System.Xml.XmlException : For security reasons DTD is prohibited in this XML document.  
    To enable DTD processing set the ProhibitDtd property on XmlReaderSettings to false  
    and pass the settings into XmlReader.Create method. 

    But how could I set the ProhibitDtd property on XmlReaderSettings to false?  The call to System.Xml.XmlTextReaderImpl.ParseDocumentContent() is a few levels below as shown in the following call stack.

    at System.Xml.XmlTextReaderImpl.Throw(Exception e) 
    at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl() 
    at System.Xml.XmlTextReaderImpl.ParseDocumentContent() 
    at System.Xml.XmlTextReaderImpl.Read() 
    at System.Xml.XPath.XPathDocument.LoadFromReader(XmlReader reader, XmlSpace space) 
    at System.Xml.XPath.XPathDocument..ctor(XmlReader reader, XmlSpace space) 
    at System.Xml.Xsl.Runtime.XmlQueryContext.ConstructDocument(Object dataSource, String uriRelative, Uri uriResolved) 
    at System.Xml.Xsl.Runtime.XmlQueryContext..ctor(XmlQueryRuntime runtime, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, WhitespaceRuleLookup wsRules) 
    at System.Xml.Xsl.Runtime.XmlQueryRuntime..ctor(XmlILCommand cmd, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, XmlSequenceWriter seqWrt) 
    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) 


    The partial HTML is shown below.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml" > 
    <body> 
    <table cellpadding="0" cellspacing="0" style="font-size: 10px" width="100%"
        <tr style="table-layout: fixed; font-size: 12px; width: 100%"
            <td colspan="2" style="width: 30%"
                &nbsp;<strong>Payment No.</strong></td
        </tr> 
        <!-- ... more html comes here ... --> 
    </table> 
    </body> 
    </html> 
     


    Thanks!
    The more you know, the less you know.
    • Edited by blackpuppy Tuesday, June 17, 2008 2:37 AM change error message to red
    Monday, June 16, 2008 9:53 AM

All replies

  • Previously I was using the following HTML.

    <html xmlns="http://www.w3.org/1999/xhtml" > 
    <body>  
    <table cellpadding="0" cellspacing="0" style="font-size: 10px" width="100%">  
        <tr style="table-layout: fixed; font-size: 12px; width: 100%">  
            <td colspan="2" style="width: 30%">  
                &nbsp;<strong>Payment No.</strong></td>  
        </tr>  
        <!-- ... more html comes here ... -->  
    </table>  
    </body>  
    </html>  

    Then I had the following error.

    System.Xml.XmlException : Reference to undeclared entity 'nbsp'. Line 22, position 18.

    The solution I got is from another post Problem with XHTML entities.

    In XML (and XHTML is XML) any entity reference except &lt;, &gt;, &amp;, &apos; and &quot; must be declared in DTD. Must, full stop.
    You need DTD declaration one way or another. Don't worry about validation - entities has nothing to do with validation and XmlTextReader can't validate anyway.
    For performance purposes you'd better have local copy of DTD and resolve to it using custom XmlResolver, this way you can avoid hitting remote server.


    Does anybody have any solution?

    Thanks a lot!

    The more you know, the less you know you know.
    Tuesday, June 17, 2008 2:56 AM
  • To load XML file XslCompiledTransform uses XmlReader.Create() method. By XmlReader don't allow DTDs. To transform XML files that have DTDs call XmlReader.Create() yourself passing correct XmlReaderSettings argument. And than pass created XmlREader to Transform() method.

    Problem 2. HTML is not an XML and includding DTD would not solve your problem. You can use SgmlXmlReader (http://code.msdn.microsoft.com/default.aspx?SiteEntry=gdn)


    WebData/Sergey
    Friday, October 17, 2008 7:49 AM