XNamespace 和 XElement 在第一个子元素上添加一个空的 xmlns 属性
XNamespace and XElement add an empty xmlns attribute on the first child element
我正在尝试使用 XElement
创建以下 XML 字符串
<Issue xmlns="http://tempuri.org/">
<p>
<Nombre>no</Nombre>
<Descripcion>asdf</Descripcion>
</p>
</Issue>
我试过下面的代码,但是这种方法向 p
元素添加了一个空的 xmlns
属性,我不想要这样:
var ns = XNamespace.Get("http://tempuri.org/");
XElement e = new XElement(ns + "Issues",
new XElement("p", new XElement("Nombre", "nme"),
new XElement("Descripcion", "dsc")));
我怎样才能避免这个问题?
注意:
我不能像这样使用 XElement.Parse
因为我需要动态构建我的 soap 请求主体:
var body = XElement.Parse("<Issue xmlns=\"http://tempuri.org/\"><p><Nombre>no</Nombre><Descripcion>asdf</Descripcion></p></Issue>");
我无法使用 Web 服务引用执行此操作,因为当存在来自 Xamarin 的引用时会出现错误。
目前我正在使用以下解决方法,但我想这不是最佳解决方案:
var xdoc = new XmlDocument();
var xissue = xdoc.CreateElement("Issue");
var attr = xdoc.CreateAttribute("xmlns");
attr.Value = "http://tempuri.org/";
xissue.Attributes.Append(attr);
var xp = xdoc.CreateElement("p");
xissue.AppendChild(xp);
var xnombre = xdoc.CreateElement("Nombre");
xnombre.InnerText = "any value";
xp.AppendChild(xnombre);
var xdescription = xdoc.CreateElement("Descripcion");
xdescription.InnerText = "any value";
xp.AppendChild(xdescription);
var e = XElement.Parse(xissue.OuterXml);
在XML中,当元素没有指定命名空间时,它会继承其最近的具有命名空间的祖先的命名空间。因此,在您的示例 XML 中,p
元素及其子元素实际上都在与 Issue
相同的命名空间中,因为它们没有 xmlns
属性,而 Issue
确实如此。
要使用 XElement
创建相同的结构,您需要确保 所有 元素指定与 Issue
相同的名称空间:
var ns = XNamespace.Get("http://tempuri.org/");
XElement e = new XElement(ns + "Issue",
new XElement(ns + "p", new XElement(ns + "Nombre", "nme"),
new XElement(ns + "Descripcion", "dsc")));
XElement
足够聪明,可以识别在将其转换为字符串时,如果它与其父项匹配,则不需要重复 xmlns
属性。
Fiddle: https://dotnetfiddle.net/QzYPoK
相反,如果您只在外部 XElement
上指定名称空间而不在内部元素上指定名称空间,那么您实际上是在说您根本不希望内部元素具有名称空间。因此,第一个子元素上的 xmlns
属性为空:它实际上是父命名空间的 "opting out"。
我正在尝试使用 XElement
创建以下 XML 字符串<Issue xmlns="http://tempuri.org/">
<p>
<Nombre>no</Nombre>
<Descripcion>asdf</Descripcion>
</p>
</Issue>
我试过下面的代码,但是这种方法向 p
元素添加了一个空的 xmlns
属性,我不想要这样:
var ns = XNamespace.Get("http://tempuri.org/");
XElement e = new XElement(ns + "Issues",
new XElement("p", new XElement("Nombre", "nme"),
new XElement("Descripcion", "dsc")));
我怎样才能避免这个问题?
注意:
我不能像这样使用 XElement.Parse
因为我需要动态构建我的 soap 请求主体:
var body = XElement.Parse("<Issue xmlns=\"http://tempuri.org/\"><p><Nombre>no</Nombre><Descripcion>asdf</Descripcion></p></Issue>");
我无法使用 Web 服务引用执行此操作,因为当存在来自 Xamarin 的引用时会出现错误。
目前我正在使用以下解决方法,但我想这不是最佳解决方案:
var xdoc = new XmlDocument();
var xissue = xdoc.CreateElement("Issue");
var attr = xdoc.CreateAttribute("xmlns");
attr.Value = "http://tempuri.org/";
xissue.Attributes.Append(attr);
var xp = xdoc.CreateElement("p");
xissue.AppendChild(xp);
var xnombre = xdoc.CreateElement("Nombre");
xnombre.InnerText = "any value";
xp.AppendChild(xnombre);
var xdescription = xdoc.CreateElement("Descripcion");
xdescription.InnerText = "any value";
xp.AppendChild(xdescription);
var e = XElement.Parse(xissue.OuterXml);
在XML中,当元素没有指定命名空间时,它会继承其最近的具有命名空间的祖先的命名空间。因此,在您的示例 XML 中,p
元素及其子元素实际上都在与 Issue
相同的命名空间中,因为它们没有 xmlns
属性,而 Issue
确实如此。
要使用 XElement
创建相同的结构,您需要确保 所有 元素指定与 Issue
相同的名称空间:
var ns = XNamespace.Get("http://tempuri.org/");
XElement e = new XElement(ns + "Issue",
new XElement(ns + "p", new XElement(ns + "Nombre", "nme"),
new XElement(ns + "Descripcion", "dsc")));
XElement
足够聪明,可以识别在将其转换为字符串时,如果它与其父项匹配,则不需要重复 xmlns
属性。
Fiddle: https://dotnetfiddle.net/QzYPoK
相反,如果您只在外部 XElement
上指定名称空间而不在内部元素上指定名称空间,那么您实际上是在说您根本不希望内部元素具有名称空间。因此,第一个子元素上的 xmlns
属性为空:它实际上是父命名空间的 "opting out"。