【问题标题】:C# Adding node in XML error: "This operation would create an incorrectly structured document."C# 在 XML 错误中添加节点:“此操作将创建结构不正确的文档。”
【发布时间】:2018-10-16 16:03:59
【问题描述】:

XML-1

<CurrentStatus>
    <Time Stamp= "12:30">
        <price>100</price>
        <amount>1</amount>
    </Time>

    <Time Stamp= "14:50">
        <price>10</price>
        <amount>5</amount>
    </Time> 

    <Time Stamp= "16:30">
        <price>10</price>
        <amount>5</amount>
    </Time>     
</CurrentStatus>

XML-2

<CurrentStatus>
    <Time Stamp= "17:22">
        <price>40</price>
        <amount>120</amount>
    </Time>               
</CurrentStatus>

我首先读取 XML-1,然后尝试将 XML-2 中的 Time 节点插入其中(XML-1):

//Read first XML
XDocument xDoc1 = XDocument.Load(@"D:\myfile1.xml");

//Read second XML
XDocument xDoc2 = XDocument.Load(@"D:\myfile2.xml");
XElement currentTimeNode = xDoc2.Descendants("Time").ToList()[0]; //first decendent
//Append data
xDoc1.AddFirst(currentTimeNode); //This line throws ERROR

问题:我想将节点添加为第一个子节点(添加Time节点的完整块)。 xDoc1.AddFirst(currentTimeNode); 行抛出以下错误:

此操作会创建结构不正确的文档。

【问题讨论】:

  • 什么是 XDocCurrent?在不知道那是什么的情况下很难说出正在发生的事情。
  • @BrootsWaymb:对不起,我重命名了变量来问这个问题。 XDocCurrent 基本上是xDoc2。更新了我的问题。
  • 我正在读取第一个 XML,然后尝试将 XML-2 中的 Time 节点插入到XDocument xDoc2。 -- 只是澄清一下,您正试图将其插入xDoc1,对吗?
  • @dbc:是的,你是对的。更新了我的问题。

标签: c# xml linq-to-xml


【解决方案1】:

您正在尝试将currentTimeNode 添加为xDoc1 的子级——但xDoc1 是XML 文档本身,这意味着您正在尝试添加currentTimeNode 作为第二个XML root element。但是,格式良好的 XML 文档必须只有一个根元素,因此 xDoc1.AddFirst(currentTimeNode) 会抛出您所看到的异常,因为它已经有一个根元素 &lt;CurrentStatus&gt;。

您应该将currentTimeNode 添加到xDoc1 的预先存在的Root:

xDoc1.Root.AddFirst(currentTimeNode);

或者,如果 xDoc1.Root 有可能为 null(因为您是在内存中从头开始构建它,而不是从预先存在的文件中加载),您可以有条件地分配它:

if (xDoc1.Root == null)
    xDoc1.Add(new XElement("CurrentStatus"));
xDoc1.Root.AddFirst(currentTimeNode);

顺便说一句,将ToList()[0] 替换为First() 可能更简单、更高效,因为一旦返回第一个元素,First() 将不会尝试枚举和具体化整个查询:

var currentTimeNode = xDoc2.Descendants("Time").First(); //first decendent

小提琴样本here.

【讨论】:

    【解决方案2】:

    FWIW - 对于可能会遇到这种情况的 VB 玩家来说。

        Dim xe1 As XElement
        Dim xe2 As XElement
    
        xe1 = <CurrentStatus>
                  <Time Stamp="12:30">
                      <price>100</price>
                      <amount>1</amount>
                  </Time>
    
                  <Time Stamp="14:50">
                      <price>10</price>
                      <amount>5</amount>
                  </Time>
    
                  <Time Stamp="16:30">
                      <price>10</price>
                      <amount>5</amount>
                  </Time>
              </CurrentStatus>
    
        xe2 = <CurrentStatus>
                  <Time Stamp="17:22">
                      <price>40</price>
                      <amount>120</amount>
                  </Time>
              </CurrentStatus>
    
        xe1.Add(xe2.<Time>) 'add to end
        ' OR
        ' xe1.AddFirst(xe2.<Time>) 'first
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      • 1970-01-01
      • 2013-05-03
      相关资源
      最近更新 更多