【问题标题】:XNamespace and XElement add an empty xmlns attribute on the first child elementXNamespace 和 XElement 在第一个子元素上添加一个空的 xmlns 属性
【发布时间】:2018-07-05 23:09:13
【问题描述】:

我正在尝试使用 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);

【问题讨论】:

    标签: c# soap linq-to-xml xelement


    【解决方案1】:

    在 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 属性。

    小提琴:https://dotnetfiddle.net/QzYPoK

    相反,如果您只在外部 XElement 上指定命名空间而不在内部指定命名空间,您实际上是在说您根本不希望内部元素具有命名空间。这会导致第一个子元素上的 xmlns 属性为空:它实际上是“退出”父命名空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      相关资源
      最近更新 更多