views:

864

answers:

2

I have an existing XDocument object that I would like to add an XML doctype to. For example:

XDocument doc = XDocument.Parse("<a>test</a>");

I can create an XDocumentType using:

XDocumentType doctype = new XDocumentType("a", "-//TEST//", "test.dtd", "");

But how do I apply that to the existing XDocument?

+1  A: 

Just pass it to the XDocument constructor (full example):

XDocument doc = new XDocument(
    new XDocumentType("a", "-//TEST//", "test.dtd", ""),
    new XElement("a", "test")
);

or use XDocument.Add (the XDocumentType has to be added before the root element):

XDocument doc = new XDocument();
doc.Add(new XDocumentType("a", "-//TEST//", "test.dtd", ""));
doc.Add(XElement.Parse("<a>test</a>"));
dtb
+1  A: 

You can add an XDocumentType to an existing XDocument, but there's a caveat: you can only do so provided no elements have already been added to the XDocument. This is mentioned in the Pro LINQ book (Google Books link). I couldn't find an MSDN page that states as much, but XmlDocument class has a similar limitation and its MSDN page states:

The DocumentType node must also be inserted before the root element of the XmlDocument (if the document already has a root element, you cannot add a DocumentType node).

That said, you would use the Add method to add an XDocumentType to an existing XDocument.

XDocument xDocument = new XDocument();
XDocumentType documentType = new XDocumentType("Books", null, "Books.dtd", null);
xDocument.Add(documentType);

On the other hand, the following is invalid and would result in an InvalidOperationException: "This operation would create an incorrectly structured document."

xDocument.Add(new XElement("Books"));
xDocument.Add(documentType);  // invalid, element added before doctype

In your case you may have to create a new XDocument then read in (transfer) the nodes from the existing XDocument.

Ahmad Mageed
Does this also apply for XDocument? The MSDN link points to XmlDocument.
dtb
@dtb: it does, but I couldn't find it stated on MSDN for XDocument. Also see the updated code and InvalidOperationException.
Ahmad Mageed