调用AddAfterSelf触发InvalidOperationException:XML文档结构非法
XML节点操作触发InvalidOperationException的解决方法
背景
我编写了两段C#代码用于生成XML结构,但组合调用时出现错误。
生成基础XML的代码
private static XNode CreateXmlFolderSchema() { XDocument document = new XDocument(new XElement("configurations")); document.Root!.Add(new XElement("config", new XAttribute("name", "RootFolder"))); return document.FirstNode!; }
这段代码生成的XML:
<configurations> <config name="RootFolder" /> </configurations>
生成文件夹节点的代码
private static XNode MapFolderToXmlDocument(Folder rootFolder, XNode parentNode) { XElement folder = new XElement("folder", new XAttribute("name", rootFolder.Name), new XAttribute("root", rootFolder.Root), new XAttribute("default", rootFolder.Default), new XAttribute("permission", rootFolder.Permission), new XAttribute("expiry", rootFolder.Expiry), CreateActionElement(rootFolder)); parentNode.AddAfterSelf(folder); return folder; }
这段代码单独生成的XML:
<folder name="/" root="false" default="false" permission="read, write" expiry="0"> <action bUploadChangePermssions="false" eUploadNewPermissions="" sUploadRename="" bUploadSubmit="false" sUploadDelete="" eDownloadIndicator="" sDownloadIndicator="" sDownloadWriteEvent="false" bChangePermissions="false" eDownloadNewPermissions="" bUploadSessionEnd="false" bDeleteOnDownload="false" /> </folder>
期望的最终XML结构
<configurations> <config name="RootFolder" /> <folder name="/" root="false" default="false" permission="read, write" expiry="0"> <action bUploadChangePermssions="false" eUploadNewPermissions="" sUploadRename="" bUploadSubmit="false" sUploadDelete="" eDownloadIndicator="" sDownloadIndicator="" sDownloadWriteEvent="false" bChangePermissions="false" eDownloadNewPermissions="" bUploadSessionEnd="false" bDeleteOnDownload="false" /> </folder> </configurations>
遇到的错误
执行MapFolderToXmlDocument(someFolderObject, CreateXmlFolderSchema())时,在parentNode.AddAfterSelf(folder)处触发InvalidOperationException,错误信息为:"This operation would create an incorrectly structured document"。经在线XML验证器确认,期望的XML结构是合法的。
问题原因
CreateXmlFolderSchema方法返回的是XML文档的根节点<configurations>。当调用AddAfterSelf时,尝试在根节点后面添加新的<folder>节点,这会导致XML文档出现多个根节点,违反了XML文档只能有一个根节点的规则,因此触发错误。
解决方案
方案一:修改CreateXmlFolderSchema返回子节点
让方法返回<config>节点而非根节点,这样AddAfterSelf会将<folder>节点添加到<config>的同级位置,也就是根节点内部:
private static XNode CreateXmlFolderSchema() { XDocument document = new XDocument(new XElement("configurations")); var configNode = new XElement("config", new XAttribute("name", "RootFolder")); document.Root!.Add(configNode); return configNode; // 返回<config>节点 }
方案二:修改MapFolderToXmlDocument的节点添加逻辑
判断传入的父节点是否为根节点,如果是,直接将<folder>节点添加到根节点的子集合中:
private static XNode MapFolderToXmlDocument(Folder rootFolder, XNode parentNode) { XElement folder = new XElement("folder", new XAttribute("name", rootFolder.Name), new XAttribute("root", rootFolder.Root), new XAttribute("default", rootFolder.Default), new XAttribute("permission", rootFolder.Permission), new XAttribute("expiry", rootFolder.Expiry), CreateActionElement(rootFolder)); if (parentNode is XElement parentElement && parentElement.Parent == null) { // 传入的是根节点,直接添加到其内部 parentElement.Add(folder); } else { parentNode.AddAfterSelf(folder); } return folder; }
内容的提问来源于stack exchange,提问作者Vocaloidas
相关产品推荐
相关产品推荐

