Search code examples
c#xmlxmldocumentxmlwriter

Need help to convert namespace code from XmlWriter to XmlDocument


for two hours I try now to translate 4 lines of old code with XmlWriter to XmlDocument, but I fail big time! ;(

XmlWriter.WriteStartDocument();
XmlWriter.WriteStartElement("document", "urn:hl7-org:v3");
XmlWriter.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
XmlWriter.WriteAttributeString("schemaLocation", "http://www.w3.org/2001/XMLSchema-instance", "urn:hl7-org:v3 GUDIDSPL.xsd");

The lines I have:

 XmlDeclaration xmlDeclaration = XmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null);
 XmlElement root = XmlDocument.CreateElement(string.Empty, "document", "urn:hl7-org:v3");
 XmlDocument.AppendChild(root);
 XmlDocument.InsertBefore(xmlDeclaration, root);

This is the only thing that works, every peace of code after that, that I tried failed. I dont get the namespaces 100% correct! One reason is that "SetAttribute", don't offer a prefix parameter.

I hope you can help.

Kind regards

Follow up issue:

I implement the code postet by "har07", which works great! But I have different issue now.

The output should look like this:

< document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 GUDIDSPL.xsd" xmlns="urn:hl7-org:v3">
<id root="1fed661f-e015-4ea9-95e5-7cf293cd0517" />
<code code="C101716" codeSystem="2.16.840.1.113883.3.26.1.1" />
<effectiveTime xsi:type="TS" value="20160212" />

But it look like this:

< document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hl7-org:v3 GUDIDSPL.xsd" xmlns="urn:hl7-org:v3">
<id root="6c4bb64e-d652-4fe6-80f1-8599196719d0" xmlns="" />
<code code="C101716" codeSystem="2.16.840.1.113883.3.26.1.1" xmlns="" />
<effectiveTime xsi:type="TS" value="20160212" xmlns="" />

My create element code generates always this empty xmlns tags. I added to my namespaceManager ("xsi", "http://www.w3.org/2001/XMLSchema-instance")


Solution

  • Using SetAttribute(), you can directly specify the prefix and the attribute local name as the first argument :

    ....
    XmlElement root = XmlDocument.CreateElement(string.Empty, "document", "urn:hl7-org:v3");
    root.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    root.SetAttribute("xsi:schemaLocation", "urn:hl7-org:v3 GUDIDSPL.xsd");
    ....
    

    Another option would be using a newer API, XDocument, instead of XmlDocument :

    XNamespace d = "urn:hl7-org:v3";
    XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
    var doc = 
        new XDocument(
            new XDeclaration("1.0", "UTF-8", null),
            new XElement(d + "document",  //create root element in default namespace
                new XAttribute("xmlns", d.ToString()), //add default namespace declaration
                new XAttribute(XNamespace.Xmlns + "xsi", xsi.ToString()), //add xsi namespace declaration
                new XAttribute(xsi + "schemaLocation", "urn:hl7-org:v3 GUDIDSPL.xsd") //add xsi:schemaLocation attribute
            )
        );
    

    UPDATE :

    Should've used SetAttribute() overload that accept namespace uri to define attribute in namespace i.e xsi:schemaLocation :

    ....
    XmlElement root = XmlDocument.CreateElement(string.Empty, "document", "urn:hl7-org:v3");
    root.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
    root.SetAttribute("schemaLocation", "http://www.w3.org/2001/XMLSchema-instance", "urn:hl7-org:v3 GUDIDSPL.xsd");
    ....