c# - LINQ to XML - How to fix default namespace in the root element -
c# - LINQ to XML - How to fix default namespace in the root element -
consider generating next xml structure, has 2 prefixed namespaces:
xnamespace ns1 = "http://www.namespace.org/ns1"; const string prefix1 = "w1"; xnamespace ns2 = "http://www.namespace.org/ns2"; const string prefix2 = "w2"; var root = new xelement(ns1 + "root", new xelement(ns1 + "e1" , new xattribute(ns1 + "attr1", "value1") , new xattribute(ns2 + "attr2", "value2")) , new xattribute(xnamespace.xmlns + prefix2, ns2) , new xattribute(xnamespace.xmlns + prefix1, ns1) );
it generates next xml result (which fine):
<w1:root xmlns:w2="http://www.namespace.org/ns2" xmlns:w1="http://www.namespace.org/ns1"> <w1:e1 w1:attr1="value1" w2:attr2="value2" /> </w1:root>
the problem arises when seek alter ns1
prefixed namespace default namespace commenting out xml declaration, in:
var root = new xelement(ns1 + "root", new xelement(ns1 + "e1" , new xattribute(ns1 + "attr1", "value1") , new xattribute(ns2 + "attr2", "value2")) , new xattribute(xnamespace.xmlns + prefix2, ns2) //, new xattribute(xnamespace.xmlns + prefix1, ns1) );
which produces:
<root xmlns:w2="http://www.namespace.org/ns2" xmlns="http://www.namespace.org/ns1"> <e1 p3:attr1="value1" w2:attr2="value2" xmlns:p3="http://www.namespace.org/ns1" /> </root>
note duplicate namespace definitions in root
, e1
, attributes prefixed p3
under e1
. how can avoid happening? how can forcefulness declaration of default namespace in root element?
i studied question: how set default xml namespace xdocument
but proposed reply replaces namespace elements without namespace defined. in samples elements , attributes have namespaces correctly set.
what have triedbased on many trial , errors, seems me attributes not straight under root node, attribute , direct parent element both have same namespace default namespace; namespace attribute needs removed!!!
based on defined next extension method traverses elements of resulting xml , performs above. in samples far extension method fixed problem successfully, doesn't mean can't produce failing illustration it:
public static void fixdefaultxmlnamespace(this xelement xelem, xnamespace ns) { if(xelem.parent != null && xelem.name.namespace == ns) { if(xelem.attributes().any(x => x.name.namespace == ns)) { var attrs = xelem.attributes().toarray(); (int = 0; < attrs.length; i++) { var attr = attrs[i]; if (attr.name.namespace == ns) { attrs[i] = new xattribute(attr.name.localname, attr.value); } } xelem.replaceattributes(attrs); } } foreach (var elem in xelem.elements()) elem.fixdefaultxmlnamespace(ns); }
this extension method produces next xml our question, desire:
<root xmlns:w2="http://www.namespace.org/ns2" xmlns="http://www.namespace.org/ns1"> <e1 attr1="value1" w2:attr2="value2" /> </root>
however don't solution, because expensive. sense i'm missing little setting somewhere. ideas?
i have found you, c# in nutshell book:
you can assign namespaces attributes too. main difference requires prefix. instance:
<customer xmlns:nut="oreilly.nutshell.csharp" nut:id="123" />
another difference unqualified attribute has empty namespace: never inherits default namespace parent element.
so given desired output have made simple check.
var xml = @"<root xmlns:w2=""http://www.namespace.org/ns2"" xmlns=""http://www.namespace.org/ns1""> <e1 attr1=""value1"" w2:attr2=""value2"" /> </root>"; var dom = xelement.parse(xml); var e1 = dom.element(ns1 + "e1"); var attr2 = e1.attribute(ns2 + "attr2"); var attr1 = e1.attribute(ns1 + "attr1"); // attr1 null ! var attrnons = e1.attribute("attr1"); // attrnons not null
so in short attr1 not have default namespace, has empty namespace.
is want? if yes, create attr1 without namespace...
new xattribute("attr1", "value1")
c# linq-to-xml xml-namespaces
Comments
Post a Comment