Vidar
Vidar

Reputation: 6673

XmlDocument.Save() inserts empty square brackets in doctype declaration

Everytime I call the method on

XmlDocument.Save(fooFilepath);

it inserts two square brackets at the end of the DOCTYPE tag e.g.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ARCXML SYSTEM "G:\ArcIMS\DTD\arcxml.dtd"[]>

Does anyone know why this might happen? I obviously don't want this to happen.

Upvotes: 16

Views: 2939

Answers (4)

Đonny
Đonny

Reputation: 940

For me this current behavior of XDocument seems wrong because

  1. It breaks round-trip. I load document with <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> and I get back <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"[]>
  2. There is space missing before the empty [].

At the moment I handle it like this but it's ugly hack:

    /// <summary>Gets string representation of a XML document.</summary>
    /// <param name="xmlDoc">The XML document.</param>
    /// <returns>String representing entire XML document.</returns>
    private static string XmlToString(XDocument xmlDoc)
    {
        var sb = new StringBuilder();
        using var xw = XmlWriter.Create(sb);
        xmlDoc.WriteTo(xw);
        xw.Flush();
        return sb.Replace(".dtd\"[]>", ".dtd\">") // Sanitization of some .NET bug(?), https://stackoverflow.com/questions/6191869/xmldocument-save-inserts-empty-square-brackets-in-doctype-declaration
                                                 .ToString();
    }

Upvotes: 0

Marc
Marc

Reputation: 19

For me it was also including blank spaces all around the xml... What worked in my case at the end is saving the document using XDocument instead of XmlDocument:

using System.Xml;
using System.Xml.Linq;

// Assuming you already have an XmlDocument named 'xmlDoc'
XmlDocument xmlDoc = new XmlDocument();
// ... Code to load/manipulate the XmlDocument ...

// Convert the XmlDocument into an XmlReader
using (XmlReader xmlReader = new XmlNodeReader(xmlDoc))
{
    // Create the XDocument from the XmlReader
    XDocument xDoc = XDocument.Load(xmlReader);

    // Modify the InternalSubset:
    if (xDoc.DocumentType != null)
    {
        xDoc.DocumentType.InternalSubset = null;
    }

    // Save the XDocument
    xDoc.Save("yourFilePath.xml");
}

Upvotes: 0

wisbucky
wisbucky

Reputation: 37827

The underlying reader used by XmlDocument (which uses XmlTextReader) does not distinguish between a document with an empty internal subset and one with no internal subset specified, so it will return InternalSubset == "" for both cases.

Then when XmlDocument.Save() is called, it sees an empty string for InternalSubset and dutifully writes an empty internal subset: [].

Unfortunately, XmlDocument.DocumentType.InternalSubset is readonly, so you cannot set it to null. You can either do:

  1. Use the lower level XmlTextWriter.WriteDocType() to have more control.

  2. Use XDocument, where you can set XDocument.DocumentType.InternalSubset = null.

Upvotes: 5

user7116
user7116

Reputation: 64068

That is a normal (and optional) part of a DOCTYPE declaration.

<!DOCTYPE rootname SYSTEM url [DTD]>

Where DTD contains any internal subset declarations to your document.

Upvotes: 7

Related Questions