How to Prevent Blank Xmlns Attributes in Output from .Net's Xmldocument

How to prevent blank xmlns attributes in output from .NET's XmlDocument?

Thanks to Jeremy Lew's answer and a bit more playing around, I figured out how to remove blank xmlns attributes: pass in the root node's namespace when creating any child node you want not to have a prefix on. Using a namespace without a prefix at the root means that you need to use that same namespace on child elements for them to also not have prefixes.

Fixed Code:

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root", "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner", "whatever:name-space-1.0"));
Console.WriteLine(xml.OuterXml);

Thanks everyone to all your answers which led me in the right direction!

Blank xmlns= after setting InnerXml on new XmlElement

The statement:

The parsing is done in the current namespace context.

means that any namespace prefixes that your XML string might contain will be interpreted in the context of the namespace prefixes that the document defines.

This causes that the following thing works:

Const ns As String = "http://test"
Const ns_foo As String = "http://www.example.com"

Dim doc As XmlDocument = New XmlDocument()
doc.LoadXml(String.Format("<data xmlns=""{0}"" xmlns:foo=""{1}""></data>", ns, ns_foo))

Dim newElement As XmlElement = doc.CreateElement("new", ns)
doc.DocumentElement.AppendChild(newElement)

newElement.InnerXml = "<foo:person><foo:name>Joe</foo:name></foo:person>"

and results in

<data xmlns:foo="http://www.example.com" xmlns="http://test">
<new>
<foo:person>
<foo:name>Joe</foo:name>
</foo:person>
</new>
</data>

However, nodes that don't have a prefix are in no particular namespace by definition. They are in the default namespace.

There is no way you can influence the default namespace when setting InnerXml. It will always be assumed that the default namespace is the empty namespace.

XmlDocument CreateElement without xmlns under a prefixed element

Because your document has default namespace declared in the most outer element you have to repeat that namespace on every child element to avoid adding additional empty one.

Change request and param elements declaration to contain "http://www.ebay.com/marketplace/search/v1/services" namespace

XmlElement request = (XmlElement)body.AppendChild(doc.CreateElement("findItemsByKeywordsRequest", "http://www.ebay.com/marketplace/search/v1/services"));
XmlElement param = (XmlElement)request.AppendChild(doc.CreateElement("keywords", "http://www.ebay.com/marketplace/search/v1/services"));

With these changes your code produces following XML:

<soap:Envelope xmlns="http://www.ebay.com/marketplace/search/v1/services" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header />
<soap:Body>
<findItemsByKeywordsRequest>
<keywords>harry potter phoenix</keywords>
</findItemsByKeywordsRequest>
</soap:Body>
</soap:Envelope>

How to remove all namespaces from XML with C#?

Well, here is the final answer. I have used great Jimmy idea (which unfortunately is not complete itself) and complete recursion function to work properly.

Based on interface:

string RemoveAllNamespaces(string xmlDocument);

I represent here final clean and universal C# solution for removing XML namespaces:

//Implemented based on interface, not part of algorithm
public static string RemoveAllNamespaces(string xmlDocument)
{
XElement xmlDocumentWithoutNs = RemoveAllNamespaces(XElement.Parse(xmlDocument));

return xmlDocumentWithoutNs.ToString();
}

//Core recursion function
private static XElement RemoveAllNamespaces(XElement xmlDocument)
{
if (!xmlDocument.HasElements)
{
XElement xElement = new XElement(xmlDocument.Name.LocalName);
xElement.Value = xmlDocument.Value;

foreach (XAttribute attribute in xmlDocument.Attributes())
xElement.Add(attribute);

return xElement;
}
return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));
}

It's working 100%, but I have not tested it much so it may not cover some special cases... But it is good base to start.

XmlWriter writing empty xmlns

I have fixed the issue by creating the document with the following code (no namespace in the document element)

XmlDocument moDocument = new XmlDocument(); 
moDocument.AppendChild(moDocument.CreateXmlDeclaration("1.0", "UTF-8", null));
moDocument.AppendChild(moDocument.CreateElement("kml"));

And by saving it with the following code to set the namespace before the save

moDocument.DocumentElement.SetAttribute("xmlns", msNamespace);
moDocument.Save(msFilePath);

This is valid as the namespce is only required in the saved xml file.



Related Topics



Leave a reply



Submit