none
How to make XmlNamespaceManager to add xmlns prefixes to the root? RRS feed

  • Question

  • I need to create an XML document based on XSD schema that contains various namespaces. There is a requirement that all namespace prefixes must be specified at the document root element. But when I do the following way

    _rootElement.AppendChild(subElement = _rootElement.OwnerDocument.CreateElement(_factory.GetPrefixOfNamespace(subSchemaElement.QualifiedName, _rootElement),
                        subSchemaElement.Name, subSchemaElement.QualifiedName.Namespace));

    with the function

            public string GetPrefixOfNamespace(XmlQualifiedName qualifiedName, XmlElement currentElement)
            {
                string prefix = _document.DocumentElement.NamespaceURI == qualifiedName.Namespace ? string.Empty : _namespaces.Single(ns => ns.Namespace == qualifiedName.Namespace).Name;
                if (!_namespaceManager.HasNamespace(prefix))
                {
                    _document.CreateNavigator().MoveToRoot();
                    //currentElement.CreateNavigator().MoveToRoot();
                    _namespaceManager.AddNamespace(prefix, qualifiedName.Namespace);
                }
                return prefix;
            }

    it specifies the xmlns prefix at the current element but not at the root of document. I've tryed to use various combinations of the commented lines and some other ones from examples I could find over the Web, but no one of them changes the situation. The namespace prefix descriptions are still placed at the current element but not at the root of the document.

    Tell me please how can I make XmlNamespaceManager to place the xmlns into the root of XML document.

    Thursday, October 25, 2012 9:23 AM

Answers

  • I've succeeded to solve this great mystery. To make the namespaces to be specified properly I had just to write the function the following way:

    public string GetPrefixOfNamespace(XmlQualifiedName qualifiedName, XmlElement currentElement)
            {
                string prefix = _document.DocumentElement.NamespaceURI == qualifiedName.Namespace ? string.Empty : _namespaces.Single(ns => ns.Namespace == qualifiedName.Namespace).Name;
                if (!_namespaceManager.HasNamespace(prefix))
                {
                    if (prefix.Length > 0)
                        _document.DocumentElement.SetAttributeNode(_document.CreateAttribute(prefix, "xmlns", qualifiedName.Namespace));
                    _namespaceManager.AddNamespace(prefix, qualifiedName.Namespace);
                }
                return prefix;
            }

    Tuesday, October 30, 2012 11:48 AM

All replies

  • You have a typical problem when creating a tree structure.  How do you add the root item.  In your code you are trying to add the root using the method _rootElement.AppendChild().  Does this make any sense?  The root properties can't be added to the child.  You have another chicken and egg problem.  which came first.  You must add the root properties before calling the child.

    Use LoadXml method like this

     XmlDocument doc = new XmlDocument();
        doc.LoadXml("<root>"+
                    "<elem>some text<child/>more text</elem>" +
                    "</root>");

    See webpage for full details

    http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.innertext.aspx


    jdweng

    Thursday, October 25, 2012 11:24 AM
  • It is not a solution in my situation. I can use InnerText property only for elements and only for their simple type values. The reason is that the document frequently changes, it can be changed with UI, WCF, DB, ect. Some optional elements can be added and removed again. So I can't reload it everytime, I need to have the same instance of XmlDocument. And I need to be sure that if some optional XML branch was added that it would be formatted properly including all nesseray updates of the document root element.

    The root element also be added multiple ways, it can be added using the same AppendChild method or it can be created by parsing of some data source. If creating root element method does matter I can try to change it, but I need to be sure that the document will be updated properly whatever was its creation way.

    Thursday, October 25, 2012 1:24 PM
  • I was only making the suggestions for adding root elements or adding new roots.  Ther doesn't seem to be another way of adding roots to the document.

    jdweng

    Thursday, October 25, 2012 1:30 PM
  • I've succeeded to solve this great mystery. To make the namespaces to be specified properly I had just to write the function the following way:

    public string GetPrefixOfNamespace(XmlQualifiedName qualifiedName, XmlElement currentElement)
            {
                string prefix = _document.DocumentElement.NamespaceURI == qualifiedName.Namespace ? string.Empty : _namespaces.Single(ns => ns.Namespace == qualifiedName.Namespace).Name;
                if (!_namespaceManager.HasNamespace(prefix))
                {
                    if (prefix.Length > 0)
                        _document.DocumentElement.SetAttributeNode(_document.CreateAttribute(prefix, "xmlns", qualifiedName.Namespace));
                    _namespaceManager.AddNamespace(prefix, qualifiedName.Namespace);
                }
                return prefix;
            }

    Tuesday, October 30, 2012 11:48 AM