You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:05:21