XmlDocument из строки XML, содержащей пользовательские пространства имен, вызывает исключение XmlException?
Мне нужно создать XmlDocument частично с помощью старого XML и частично с помощью создания нового. Проблема в том, что старый XML содержит пользовательские пространства имен, и я не могу их использовать, когда получаю исключение XmlException. Я пытался добавить пространство имен для многих разных мест, но я не могу преодолеть исключение!
Исключение
System.Xml.XmlException was unhandled by user code
Message='my' is an undeclared prefix. Line 1, position 42.
Source=System.Xml
Мой код
XmlDocument doc = new XmlDocument();
XmlSchema schema = new XmlSchema();
schema.Namespaces.Add("my", "http://foobar.com/");
doc.Schemas.Add(schema);
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(dec);
XmlElement root = doc.CreateElement("root");
root.SetAttribute("xmlns:my", "http://foobar.com/");
doc.AppendChild(root);
foreach (var item in GetItems())
{
XmlElement elem = doc.CreateElement("item");
elem.SetAttribute("id", item.id);
// Append body to elem
XmlElement body = doc.CreateElement("body");
body.InnerXml = item.Body; // Here is where I get the exception
elem.AppendChild(body);
// Append elem to root
root.AppendChild(elem);
}
Вход от Item.Body похож на
<aaa><bbb my:attr="55">Foo</bbb></aaa>
Я ожидал, что результат будет похож на
<?xml version="1.0" encoding="utf-8"?>
<root my:attr="http://foobar.com/">
<item id="12345">
<body>
<aaa>
<bbb my:attr="55">Foo</bbb>
</aaa>
</body>
</item>
</root>
Я открыт для альтернатив использования этого метода. После создания XmlDocument я просто распечатываю его, проверяю по схеме и затем выдвигаю его для просмотра пользователю.
1 ответ
Решение
Вот обходной путь, лучше всего я могу придумать:
XNamespace my = "http://foobar.com/";
var doc = new XDocument(new XElement("root",
new XAttribute(XNamespace.Xmlns + "my", my)));
var body = new XElement("body");
doc.Root.Add(new XElement("item", new XAttribute("id", 12345), body));
string innerItem = @"<aaa><bbb my:attr=""55"">Foo</bbb></aaa>";
string itemWrap = @"<wrap xmlns:my=""http://foobar.com/"">" + innerItem + "</wrap>";
XElement item = XElement.Parse(itemWrap);
body.Add(item.Element("aaa"));
Console.WriteLine(doc);