【问题标题】:XElement.Element returning null for newly created elementXElement.Element 为新创建的元素返回 null
【发布时间】:2013-05-08 07:35:12
【问题描述】:

我正在使用XElement 创建一个XMLDocument,该XMLDocument 在分层WPF 树视图中使用。如果我创建一个新元素:

    x_element = new XElement("node",
    new XElement("tree_id", strData[0]),
    new XElement("sys_id", dpl.DepSysId),
    new XElement("part_id", strData[8]),
    new XElement("make", strData[6]),
    new XElement("model", strData[5]),
    new XElement("level", strData[2]));

然后我需要向“节点”添加属性,所以我尝试了:

   XElement temp_el = x_element.Element("node"); // This is returning null
   temp_el.SetAttributeValue("title", strData[7] + " " + strData[6] + " " + strData[5]);
   temp_el.SetAttributeValue("canEdit", "False");
   temp_el.SetAttributeValue("status", nStatus.ToString());
   temp_el.SetAttributeValue("qty", strData[13]);
   temp_el.SetAttributeValue("part", strData[8]);

在上面的代码中 temp_el 为空,但我可以在调试器中看到 x_element 包含以下内容:

<node>
  <tree_id>82</tree_id>
  <sys_id>82</sys_id>
  <part_id>169</part_id>
  <make>ST Panel</make>
  <model>Logical Pure 16 tube Collector</model>
  <level>0</level>
</node>

为了解决这个问题,我使用了以下方法:

   foreach (XElement temp_el in x_element.DescendantsAndSelf())
   {
       if (temp_el.Name == "node")
       {
           temp_el.SetAttributeValue("title", strData[7] + " " + strData[6] + " " + strData[5]);
           temp_el.SetAttributeValue("canEdit", "False");
           temp_el.SetAttributeValue("status", nStatus.ToString());
           temp_el.SetAttributeValue("qty", strData[13]);
           temp_el.SetAttributeValue("part", strData[8]);
           break;
       }
   }

虽然上述工作有效,但我只是好奇为什么会返回 null。我的解决方法是最好的方法吗?

问候。

【问题讨论】:

  • 答案解决了问题所在,但就最佳方法而言:new XElement 的构造函数允许您还添加new XAttributes 以及您已经添加的new XElements。

标签: c# xml linq xelement


【解决方案1】:

您这样定义 XElement:

x_element = new XElement("node", /* child nodes */);

其中"node" 是您正在创建的XElement 的名称,以下参数是它的子项。

通过使用x_element.Node("node"),你试图获取名为"node"的子节点,并且没有这样的子节点。
x_element 本身是名为的节点“节点”。
DescendantsAndSelf 有效,因为它包含 x_element(因此是“AndSelf”),但您也不需要这个,因为您已经有了节点。

因此您可以将第二个代码 sn-p 更改为:

x_element.SetAttributeValue("title", strData[7] + " " + strData[6] + " " + strData[5]);
x_element.SetAttributeValue("canEdit", "False");
// etc.

(顺便说一句,你也可以在构造函数中添加属性)

【讨论】:

  • 感谢您的回复和解释,它确实有助于澄清我对 XElements 的理解。
【解决方案2】:

因为有了你的第一个temp_el

XElement temp_el = x_element.Element("node");

您曾经获取不被视为 x_element 的元素的节点。

它被视为它的根。但是,对于第二个,

x_element.DescendantsAndSelf()`

您使用了这个XElement 方法将节点本身视为一个元素。

XContainer.Elements Method - 按文档顺序返回此元素或文档的子元素的集合。

XElement.DescendantsAndSelf Method - 按文档顺序返回包含此元素以及此元素的所有后代元素的元素集合。

【讨论】:

    【解决方案3】:

    为了解决这个问题,我使用了 Descendants()。这是我的代码 sn-p

    public void UpdateEnquiry([FromBody]XElement UpdatePurchaseOrder)
            {
                var obj = XElement.Parse(UpdatePurchaseOrder.ToString());
                var ii = (from v in obj.Descendants() select new { v.Value }).ToList() ;
             }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-26
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多