C# Adding node in XML error: "This operation would create an incorrectly structured document."
C# Adding node in XML error: "This operation would create an incorrectly structured document."
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,然后尝试将 Time
节点从 XML-2 插入其中( 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);
行抛出以下错误:
This operation would create an incorrectly structured document.
您正在尝试将 currentTimeNode
添加为 xDoc1
的子项——但是 xDoc1
是 XML 文档本身,这意味着您正在尝试添加 currentTimeNode
作为第二个 XML root element。但是,一个格式正确的 XML 文档必须只有一个根元素,因此 xDoc1.AddFirst(currentTimeNode)
会抛出您看到的异常,因为它已经有一个根元素 <CurrentStatus>
.
相反,您应该将 currentTimeNode
添加到 xDoc1
的现有 Root
中:
xDoc1.Root.AddFirst(currentTimeNode);
或者,如果 xDoc1.Root
有可能为空(因为您是在内存中从头开始构建它而不是从预先存在的文件加载),您可以有条件地分配它:
if (xDoc1.Root == null)
xDoc1.Add(new XElement("CurrentStatus"));
xDoc1.Root.AddFirst(currentTimeNode);
顺便说一句,替换 ToList()[0]
with First()
可能更简单、性能更高,因为一旦返回第一个元素,First()
将不会尝试枚举和具体化整个查询:
var currentTimeNode = xDoc2.Descendants("Time").First(); //first decendent
示例 fiddle here.
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
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,然后尝试将 Time
节点从 XML-2 插入其中( 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);
行抛出以下错误:
This operation would create an incorrectly structured document.
您正在尝试将 currentTimeNode
添加为 xDoc1
的子项——但是 xDoc1
是 XML 文档本身,这意味着您正在尝试添加 currentTimeNode
作为第二个 XML root element。但是,一个格式正确的 XML 文档必须只有一个根元素,因此 xDoc1.AddFirst(currentTimeNode)
会抛出您看到的异常,因为它已经有一个根元素 <CurrentStatus>
.
相反,您应该将 currentTimeNode
添加到 xDoc1
的现有 Root
中:
xDoc1.Root.AddFirst(currentTimeNode);
或者,如果 xDoc1.Root
有可能为空(因为您是在内存中从头开始构建它而不是从预先存在的文件加载),您可以有条件地分配它:
if (xDoc1.Root == null)
xDoc1.Add(new XElement("CurrentStatus"));
xDoc1.Root.AddFirst(currentTimeNode);
顺便说一句,替换 ToList()[0]
with First()
可能更简单、性能更高,因为一旦返回第一个元素,First()
将不会尝试枚举和具体化整个查询:
var currentTimeNode = xDoc2.Descendants("Time").First(); //first decendent
示例 fiddle here.
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