Controlling the order of XML namepaces
Asked Answered
S

7

3

I'm having a problem getting the "xmlns" to appear first in the root attribute list.

Im getting this:

  <myroot 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.someurl.com/ns/myroot http://www.someurl.com/xml/schemas/myschema.xsd"
        xmlns="http://www.someurl.com/ns/myroot"> 

       <sometag>somecontent</sometag>

    </myroot>

And i want this:

<myroot 
        xmlns="http://www.someurl.com/ns/myroot" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.someurl.com/ns/myroot http://www.someurl.com/xml/schemas/myschema.xsd">

       <sometag>somecontent</sometag>

    </myroot>

My code looks like this:

  XNamespace rt = "http://www.someurl.com/ns/myroot";
        XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";

        var submissionNode = new XElement(XmlNameSpaces.rt + "myroot");
        submissionNode.Add(new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"));
        submissionNode.Add(new XAttribute(xsi + "schemaLocation", @"http://www.someurl.com/ns/myroot http://www.someurl.com/xml/schemas/myschema.xsd"););

What do i need to do different to change the order?

EDIT: I understand the order is not normally relavent, but its a requirement in this case.

Sanctimonious answered 7/4, 2009 at 10:26 Comment(0)
B
2

IIRC, the order of attributes (in xml) is unimportant... so why change it? Is it causing an actual problem?

Boughton answered 7/4, 2009 at 10:29 Comment(10)
/seconded - the whole point of XML is that things like this are non-issuesBurglar
@Marc: The order might be important when signing an XML document / validating a digital signature. There is a W3C recommendation called Canonical XML (w3.org/TR/xml-c14n.html) to handle specifically such use cases.Burtis
@divo - hence the question; if that is the problem, it is worth effort. If it is purely cosmetic, it probably isn't.Boughton
In XML Digital Signature, it is the canonical XML that is signed, not the original source.Aldrin
@John: Yes, that is obviously true. But the OP didn't give a reason why the order matters to him, so he might just want to do that?Burtis
@Marc I agree, but in this case my client as said the order is important.Sanctimonious
Downvoting this answer because it's not an answer; this is a question and should have been a comment to the OP.Vinitavinn
@kent well, that's up to you; there are no valid scenarios where this should matter, however. Pointing out that it is a non-issue has some validity, IMO.Boughton
@MarcGravell, it's fine to question the validity of the OP. But it should be done as a Comment on the OP, not as an Answer. This answer is 2 questions. And as Dan updated his question, it is a project requirement. Maybe not a good requirement, but a requirement nonetheless. This answer does not address the question.Vinitavinn
@Vinitavinn you'll forgive me for attempting to help based on the question that was there at the time I answered, and not the one that was there 2 hours later, I hopeBoughton
H
2

Attribute ordering is NOT specified in the XML document, and shouldn't be relied upon. It may be worth looking at the spec

You'll find that if you read a XML document into a DOM, and write it out, regardless of the platform/library, you can't (and shouldn't) rely on the attribute ordering. It's a common misconception, btw!

Hanako answered 7/4, 2009 at 10:49 Comment(3)
Thanks, its just the ordering is a requirement of the organisation im submitting the xml too.Sanctimonious
Mmm. Sounds like they have a problem at their end :-) You may want to see if you can influence thatHanako
Downvoting. While this "answer" is factually correct, it does not answer the question in the OP.Vinitavinn
F
2

I have a customer with this very problem. This was a real pain in the s, so I wrote a workaround to solve this.

Please note this is not a beautiful solution, and this should be not encouraged, but works.

public static class MyKludgeXmlClass
{
    public static XmlDocument CreateXmlDocumentWithOrderedNamespaces()
    {
        var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><MyRoot xmlns=\"http://www.example.com/schemas/1.0/VRSync\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.example.com/schemas/1.0/VRSync http://xml.example.com/vrsync.xsd\"></MyRoot>";
        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        doc.LoadXml(xml);

        return doc;
    }
}

With XmlDocument you can retrieve the root:

var xmlDoc = MyKludgeXmlClass.CreateXmlDocumentWithOrderedNamespaces();
XmlElement root = xmlDoc.DocumentElement;

And append children nodes using your favorite method.

Forcer answered 29/3, 2016 at 6:13 Comment(0)
P
2

Because sometimes the right answer is to say, no, don't do that...

Per W3C Namespaces in XML Recommendation, section 3 Declaring Namespaces:

[Definition: A namespace (or more precisely, a namespace binding) is declared using a family of reserved attributes. Such an attribute's name must either be xmlns or begin xmlns:. These attributes, like any other XML attributes, may be provided directly or by default. ]

Therefore, the order of namespace declarations, like the order of any attributes, is insignificant.

So, no conformant XML tool or library will care about the order of namespace declarations, and neither should you.

Presidency answered 23/10, 2016 at 2:1 Comment(2)
What about when creating a canonical version of the xml?Shepherd
@daneejela: See this answer for links relevant to normalize/canonical standards, but realize that their existence doesn't change the fact that order of namespace declarations, like attributes, is insignificant in XML, so XML parsers and other XML libraries aren't going to help you achieve an ordering. You'll need specialized serializers, and even then you'll be fighting other consumers/producers to maintain that insignificant ordering.Presidency
B
1

Would XmlWriter be an option for you?

Afaik, it gives you full control of the order of attributes and namespace declarations.

Burtis answered 7/4, 2009 at 10:48 Comment(5)
Indeed (+1); since it is one-way, it can't do anything other than push things out in the order you supply them. A very different beast, though.Boughton
Is this is the only way to achieve this? Iv already completed the document creation which is quite involved, dont really want to have to re-do using xmlwriterSanctimonious
If attribute order is important, what your client is asking you to produce is not really XML. So you'll need to take your own steps to serialise it in whatever way is specified by your client.Salish
@Dan, you don't have to redo your work. You could also write your XDocument to a filtering XmlWriter which would do a post-processing on your XML stream.Burtis
@DirkVollmar Can you take a look at this question? I've tried using XmlWriter to do this, but it still seems to write stuff out of order.Christianism
B
0

Software that requires attributes to be in a specified order doesn't conform to the XML recommendation.

The first question you should be asking is not, "How can I produce XML with namespace attributes in a defined order?" Instead, it should be, "What are the other respects in which this software doesn't conform to the XML recommendation?" Because I will bet you one crisp new American dollar that if the recipient's process violates the XML recommendation in one respect, it violates it in at least one other.

Baresark answered 7/4, 2009 at 18:19 Comment(1)
Downvoting. Again, factually correct but not an answer to the question asked.Vinitavinn
M
0

You can control the order of the xmlns attribute by explicitly adding it as a regular XAttribute. It will then appear in the order it was added:

XNamespace rt = "http://www.someurl.com/ns/myroot";
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";

var submissionNode = new XElement(rt + "myroot");
submissionNode.Add(new XAttribute("xmlns", rt)); // <-- manually add the namespace as the first regular attribute
submissionNode.Add(new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"));
submissionNode.Add(new XAttribute(xsi + "schemaLocation", "http://www.someurl.com/ns/myroot http://www.someurl.com/xml/schemas/myschema.xsd"));

var xml = submissionNode.ToString();
Console.WriteLine(xml);
Trace.Assert(xml == """<myroot xmlns="http://www.someurl.com/ns/myroot" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.someurl.com/ns/myroot http://www.someurl.com/xml/schemas/myschema.xsd" />""");

(BTW, there is also canonical XML that sorts namespace attributes in the order you want them to be as well. But since it also comes with many other properties, it might not format the rest of the document in a way you want it to be. In case you want to look into it anyway, I gave an answer to a different question that contains code to generate a C14N (canonical XML) representation from an existing XmlDocument object.)

Mauer answered 30/11, 2023 at 16:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.