如何编写 XDocument 并始终保持相同的命名空间前缀?
How do I compose XDocument and keep the same namespace prefix throughout?
我在编写使用两个名称空间的 XDocument 时遇到问题。当我添加由不同方法(引用完全相同的 XNamespace 实例)创建的 XElements 时,我得到了具有不同前缀的 xmlns 的重新声明。它完全正确 XML,但对人类可读性来说是个熊。
XDocument xml = new XDocument();
XElement e_graphml = new XElement(ns_graphML + "graphml",
new XAttribute("xmlns", ns_graphML),
new XAttribute(XNamespace.Xmlns + "y", ns_yGraphML));
xml.Add(e_graphml);
XElement child = graph.ToX();
e_graphml.Add(child);
图形对象使用全局可用的 ns_graphML 和 ns_yGraphML 对象,它们都是 XNamespace 类型。然而,我返回的 XML 序列化为文本:
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:y="http://www.yworks.com/xml/graphml">
<graph p3:edgedefault="directed" p3:id="fileReferences" xmlns:p3="http://graphml.graphdrawing.org/xmlns" />
</graphml>
(编辑)
我预计:
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:y="http://www.yworks.com/xml/graphml">
<graph edgedefault="directed" id="fileReferences"/>
</graphml>
(/编辑)
图形元素添加到 e_graphml 后应该继承默认的 xmlns,但显然这些被认为是不同的。请注意,graph.ToX() 不会将显式名称空间属性 (xmlns=...) 添加到返回的图形 XElement;其中的 XNames 只是引用命名空间,如下所示:
XElement e_graph = new XElement(ns_graphML + "graph",
new XAttribute(ns_graphML + "edgedefault", "directed"),
new XAttribute(ns_graphML + "id", Name));
也许这是 Force XDocument to not use namespace prefix if namespace is also defined as default 的副本,但我完全用代码创建 XDocument,而不是从初始 XML 文本创建。
我认为这种行为是故意的。没有名称空间前缀的属性不是任何名称空间的一部分,甚至不是默认名称空间。它需要将该属性放入该名称空间中,但由于它没有要使用的前缀,因此必须创建一个。我认为仅创建文档但为名称空间使用显式前缀会更容易,这样会更清晰。
var e_graphml = new XElement(ns_graphML + "graphml",
new XAttribute(XNamespace.Xmlns + "g", ns_graphML),
new XAttribute(XNamespace.Xmlns + "y", ns_yGraphML)
);
这将产生 xml,如下所示:
<g:graphml xmlns:g="http://graphml.graphdrawing.org/xmlns" xmlns:y="http://www.yworks.com/xml/graphml">
<g:graph g:edgedefault="directed" g:id="fileReferences" />
</g:graphml>
如果您特别想让它呈现不带前缀的属性,请在生成它们时删除命名空间。除非明确要求,否则属性通常不需要命名空间。
var e_graph = new XElement(ns_graphML + "graph",
new XAttribute("edgedefault", "directed"),
new XAttribute("id", Name)
);
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:y="http://www.yworks.com/xml/graphml">
<graph edgedefault="directed" id="fileReferences" />
</graphml>
我在编写使用两个名称空间的 XDocument 时遇到问题。当我添加由不同方法(引用完全相同的 XNamespace 实例)创建的 XElements 时,我得到了具有不同前缀的 xmlns 的重新声明。它完全正确 XML,但对人类可读性来说是个熊。
XDocument xml = new XDocument();
XElement e_graphml = new XElement(ns_graphML + "graphml",
new XAttribute("xmlns", ns_graphML),
new XAttribute(XNamespace.Xmlns + "y", ns_yGraphML));
xml.Add(e_graphml);
XElement child = graph.ToX();
e_graphml.Add(child);
图形对象使用全局可用的 ns_graphML 和 ns_yGraphML 对象,它们都是 XNamespace 类型。然而,我返回的 XML 序列化为文本:
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:y="http://www.yworks.com/xml/graphml">
<graph p3:edgedefault="directed" p3:id="fileReferences" xmlns:p3="http://graphml.graphdrawing.org/xmlns" />
</graphml>
(编辑) 我预计:
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:y="http://www.yworks.com/xml/graphml">
<graph edgedefault="directed" id="fileReferences"/>
</graphml>
(/编辑)
图形元素添加到 e_graphml 后应该继承默认的 xmlns,但显然这些被认为是不同的。请注意,graph.ToX() 不会将显式名称空间属性 (xmlns=...) 添加到返回的图形 XElement;其中的 XNames 只是引用命名空间,如下所示:
XElement e_graph = new XElement(ns_graphML + "graph",
new XAttribute(ns_graphML + "edgedefault", "directed"),
new XAttribute(ns_graphML + "id", Name));
也许这是 Force XDocument to not use namespace prefix if namespace is also defined as default 的副本,但我完全用代码创建 XDocument,而不是从初始 XML 文本创建。
我认为这种行为是故意的。没有名称空间前缀的属性不是任何名称空间的一部分,甚至不是默认名称空间。它需要将该属性放入该名称空间中,但由于它没有要使用的前缀,因此必须创建一个。我认为仅创建文档但为名称空间使用显式前缀会更容易,这样会更清晰。
var e_graphml = new XElement(ns_graphML + "graphml",
new XAttribute(XNamespace.Xmlns + "g", ns_graphML),
new XAttribute(XNamespace.Xmlns + "y", ns_yGraphML)
);
这将产生 xml,如下所示:
<g:graphml xmlns:g="http://graphml.graphdrawing.org/xmlns" xmlns:y="http://www.yworks.com/xml/graphml">
<g:graph g:edgedefault="directed" g:id="fileReferences" />
</g:graphml>
如果您特别想让它呈现不带前缀的属性,请在生成它们时删除命名空间。除非明确要求,否则属性通常不需要命名空间。
var e_graph = new XElement(ns_graphML + "graph",
new XAttribute("edgedefault", "directed"),
new XAttribute("id", Name)
);
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:y="http://www.yworks.com/xml/graphml">
<graph edgedefault="directed" id="fileReferences" />
</graphml>