【问题标题】:How do I compose XDocument and keep the same namespace prefix throughout?如何编写 XDocument 并始终保持相同的命名空间前缀?
【发布时间】:2016-12-27 02:44:03
【问题描述】:

我在编写使用两个命名空间的 XDocument 时遇到问题。当我添加由不同方法创建的 XElements(指的是完全相同的 XNamespace 实例)时,我会重新声明具有不同前缀的 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 文本。

【问题讨论】:

  • 粘贴一个实际 xml 应该是什么样子的示例。

标签: xml namespaces linq-to-xml xelement


【解决方案1】:

我认为这种行为是有意的。没有命名空间前缀的属性不属于任何命名空间,甚至不是默认命名空间。它需要将属性放在该名称空间中,但由于它没有要使用的前缀,因此必须创建一个。我认为只创建文档但对命名空间使用显式前缀会更容易,这样会更简洁。

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>

【讨论】:

  • 没有前缀那么可取,但它会做。我现在得到的正是你所说的。
  • 如果您只想不将前缀添加到属性中,您只需从该命名空间中删除属性即可。它应该完全按照您的意愿提供。
猜你喜欢
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
  • 2021-01-25
相关资源
最近更新 更多