我尝试将以下xml文档(简化(编程为代码:
<P xmlns="http://schemas.microsoft.com/x/2010/manifest"
xmlns:ab="http://schemas.microsoft.com/a/2010/manifest"
xmlns:ac="http://schemas.microsoft.com/a/2013/manifest">
<ab:Ex xmlns:ab="http://schemas.microsoft.com/a/2013/manifest">
</ab:Ex>
</P>
现在,一个元素重新定义了命名空间:
xmlns:ab="http://schemas.microsoft.com/a/2013/manifest".
如何将元素放入我的程序中?这显然是有效的,因为我可以像这样加载 xml 文件:
Add(new XAttribute (XNamespace.Xmlns + "ab")
我收到错误消息:
System.Xml.XmlException:"前缀'ab'不能在同一起始元素标签中从'http://schemas.microsoft.com/a/2010/manifest'重新定义为'http://schemas.microsoft.com/a/2013/manifest'。
实际上是合乎逻辑的(重新定义(,但是当我加载文档时,该元素被接受。
using System.Xml.Linq;
namespace xmltest
{
class Program
{
static void Main(string[] args)
{
//Load
XDocument doc1 = XDocument.Load(@"c:simple.xml", LoadOptions.None);
System.Console.WriteLine(doc1.ToString());
//Create new
XNamespace ab = "http://schemas.microsoft.com/a/2010/manifest";
XNamespace nsx = "http://schemas.microsoft.com/x/2010/manifest";
XDocument doc2 = new XDocument(new XDeclaration("1.0", "utf-8", ""),
new XElement(nsx + "P"));
doc2.Element(nsx + "P").Add(new XAttribute("xmlns",
"http://schemas.microsoft.com/x/2010/manifest"));
doc2.Element(nsx + "P").Add(new XAttribute(XNamespace.Xmlns + "ab",
"http://schemas.microsoft.com/a/2010/manifest"));
doc2.Element(nsx + "P").Add(new XAttribute(XNamespace.Xmlns + "ac",
"http://schemas.microsoft.com/a/2013/manifest"));
XElement xml = new XElement(ab + "Ex");
//--> Below does not work work
xml.Add(new XAttribute(XNamespace.Xmlns + "ab",
"http://schemas.microsoft.com/a/2013/manifest"));
doc2.Element(nsx + "P").Add(xml);
System.Console.WriteLine(doc2.ToString());
}
}
}
有人知道如何解决这个问题吗?
理论上,因为
<ab:Ex xmlns:ab="http://schemas.microsoft.com/a/2013/manifest">
实际上意味着 Ex 要在新命名空间(2013 年(中定义,您可以通过在新命名空间中定义 Ex 来获得您想要的内容,即:
XNamespace abOld = "http://schemas.microsoft.com/a/2010/manifest";
XNamespace abNew = "http://schemas.microsoft.com/a/2013/manifest";
XNamespace nsx = ...
XElement xml = new XElement(abNew + "Ex");
xml.Add(new XAttribute(XNamespace.Xmlns + "ab",
"http://schemas.microsoft.com/a/2013/manifest"));
但是,重新调整现有命名空间的别名,以便您可以使用相同的别名,这将对将来的维护造成真正的混淆 - 当别名离开范围时,它将恢复到它的旧定义。我建议您至少为 2010 和 2013 命名空间创建不同的、唯一的别名。
此外,除非 Xml 的预期使用者有问题,并且需要特定的别名或命名空间作用域,否则我通常会避免微观管理命名空间别名和命名空间范围 - 让 Linq to Xml 为您管理。
例如,如何只是:
XNamespace abOld = "http://schemas.microsoft.com/a/2010/manifest";
XNamespace abNew = "http://schemas.microsoft.com/a/2013/manifest";
// Build up the document by providing element, attribute + applicable namespaces:
var root = new XElement(abOld + "P",
new XElement(abNew + "Ex"));