Можно ли создать XmlElement с двумя пространствами имен xml? - PullRequest
1 голос
/ 13 октября 2019

Я должен сгенерировать XML, как показано ниже:

<foo:document xmlns="http://www.example.com/xmlns" xmlns:foo="http://www.example.com/xmlns/foo-version1">
    <foo:bar foo:baz="true" />
</foo:document>

Как мне сгенерировать этот документ с System.Xml.XmlDocument в c #?

Ответы [ 2 ]

1 голос
/ 13 октября 2019

Это можно сделать следующим образом:

var fooNs = "http://www.example.com/xmlns/foo-version1";
var defNs = "http://www.example.com/xmlns";

var doc = new XmlDocument();

// Create and add the root element
var root = doc.CreateElement("foo", "document", fooNs);
doc.AppendChild(root);

// Add the default namespace (do note the root element is not in this namespace)
var defAttr = doc.CreateAttribute("xmlns");
defAttr.Value = defNs;
root.Attributes.Append(defAttr);

// Create the <foo:bar> element
var bar = doc.CreateElement("foo", "bar", fooNs);
var bazAttr = doc.CreateAttribute("foo", "baz", fooNs);
bazAttr.Value = XmlConvert.ToString(true);
bar.Attributes.Append(bazAttr);

// Add it to the root
root.AppendChild(bar);

Примечания:

  • При создании узлов XmlElement и XmlAttribute в пространстве имен всегда предпочитайтеиспользуйте перегрузки Create(), которые принимают префикс, localName и namespaceURI:


    С семантической точки зрения, что действительно важно, так это локальное имя узла и пространство имен;префикс - это просто поиск, чтобы найти объявление пространства имен в области видимости.

  • Заметьте, я не добавил явно атрибут xmlns:foo="http://www.example.com/xmlns/foo-version1"? В этом нет необходимости, поскольку корневой элемент был создан с использованием требуемого пространства имен и префикса через doc.CreateElement("foo", "document", fooNs). Каркас (XmlWriter) автоматически выдаст атрибут xmlns:foo при записи XmlDocument в XML.

    Если по какой-то причине вам необходимо явно создать атрибут пространства имен, вы можете сделать это следующим образом:

    // The following is redundant as the framework (XmlWriter) will add the necessary
    // xmlns:foo attribute as the XmlDocument is being written.  If you need to do it anway 
    // (e.g. to control the order) you can do it as follows.
    // (But note that XML attributes are unordered according to the XML specification, for details
    // see https://stackoverflow.com/questions/33746224/in-xml-is-the-attribute-order-important)
    var xmlnsNs = "http://www.w3.org/2000/xmlns/";
    
    var fooAttr = doc.CreateAttribute("xmlns", "foo", xmlnsNs);
    fooAttr.Value = fooNs;
    root.Attributes.Append(fooAttr);
    

Демонстрационная скрипка # 1 здесь .

Кстати, как написано в комментариях, сделать это намного проще с LINQ to XML :

XNamespace fooNs = "http://www.example.com/xmlns/foo-version1";
XNamespace defNs = "http://www.example.com/xmlns";

var root = new XElement(fooNs + "document"
                        // Add the namespace declarations with your desired prefixes.  Be sure to pass them into the constructor.
                        , new XAttribute("xmlns", defNs.ToString())
                        , new XAttribute(XNamespace.Xmlns + "foo", fooNs.ToString())
                        // And add any required content.  The content can be passed into the constructor, or added later. 
                        , new XElement(fooNs + "bar", new XAttribute(fooNs + "baz", true)));

Примечания:

  • С LINQ to XML вам никогда не нужно беспокоиться о префиксе пространства именXElement или XAttribute. Просто создайте их с правильным пространством имен и локальным именем, инкапсулированным в XName. Каркас (XmlWriter) будет автоматически испускать все необходимые атрибуты пространства имен при записи.

    Но если вам по какой-то причине необходимо настроить пространства имен, вы можете сконструировать соответствующие XAttribute объекты и затем передать их в конструктор XElement .

  • Подробнее см. Как: создать документ с пространствами имен (C #) (LINQ to XML) .

Демонстрационная скрипка # 2 здесь .

0 голосов
/ 13 октября 2019

Сетевая библиотека хочет, чтобы пространство имен по умолчанию (без префикса) было последним пространством имен. Я обычно просто использую метод Parse, который имеет меньше ограничений. Смотрите код ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = "<foo:document xmlns=\"http://www.example.com/xmlns\" xmlns:foo=\"http://www.example.com/xmlns/foo-version1\">" +
                         "   <foo:bar foo:baz=\"true\" />" +
                         "</foo:document>";

            XDocument doc = XDocument.Parse(xml);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...