这个文件或代码有什么问题?

What is wrong with this file or code?

发生了什么\有什么区别? 我正在尝试 return 来自 XML 文件的特定节点。

XML 文件:

  <?xml version="1.0" encoding="utf-8"?>
    <JMF SenderID="InkZone-Controller" Version="1.2">
      <Command ID="cmd.00695" Type="Resource">
        <ResourceCMDParams ResourceName="InkZoneProfile" JobID="K_41">
          <InkZoneProfile ID="r0013" Class="Parameter" Locked="false" Status="Available" PartIDKeys="SignatureName SheetName Side Separation" DescriptiveName="Schieberwerte von DI" ZoneWidth="32">
            <InkZoneProfile SignatureName="SIG1">
              <InkZoneProfile Locked="False" SheetName="S1">
                <InkZoneProfile Side="Front" />
              </InkZoneProfile>
            </InkZoneProfile>
          </InkZoneProfile>
        </ResourceCMDParams>
      </Command>
<InkZoneProfile Separation="Cyan" ZoneSettingsX="0 0,005 " />
    </JMF>

代码:

           XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("C:\test\test.xml");
            XmlNode root = xmlDoc.DocumentElement;
            var parent = root.SelectSingleNode("/JMF/Command/ResourceCmdParams/InkZoneProfile/InkZoneProfile/InkZoneProfile/InkZoneProfile");

            XmlElement IZP = xmlDoc.CreateElement("InkZoneProfile");
            IZP.SetAttribute("Separation", x.colorname);
            IZP.SetAttribute("ZoneSettingsX", x.colorvalues);
            xmlDoc.DocumentElement.AppendChild(IZP);
            xmlDoc.Save("C:\test\test.xml");

父变量 return 为空。我调试过,root 和 xmlDoc 在它们的内部文本中有 XML 内容。 但是,这里进行了测试(由用户@har07 对上一个问题进行了测试: 工作没有问题。 https://dotnetfiddle.net/vJ8h9S

这两者有什么区别?他们基本上遵循相同的代码,但一个有效,另一个无效。
调试时我发现 root.InnerXml 本身加载了内容(与 XmlDoc.InnerXml 相同)。但是 InnerXml 没有实现 SelectSingleNode 的方法。我相信如果我将它保存到一个字符串中,我可能会丢失缩进等。

有人能告诉我有什么区别或有什么问题吗?谢谢 ! XML 样本:https://drive.google.com/file/d/0BwU9_GrFRYrTUFhMYWk5blhhZWM/view?usp=sharing

SetAttribute 不会为您自动转义字符串。因此,它会使您的 XML 文件无效。

来自 MSDN 关于 XmlElement.SetAttribute

Any markup, such as syntax to be recognized as an entity reference, is treated as literal text and needs to be properly escaped by the implementation when it is written out

在您的代码中找到所有包含 SetAttribute 的行并使用 SecurityElement.Escape 转义该值。

例如:更改这些行:

IZP.SetAttribute("Separation", x.colorname);
IZP.SetAttribute("ZoneSettingsX", x.colorvalues);

收件人:

using System.Security;

IZP.SetAttribute("Separation", SecurityElement.Escape(x.colorname));
IZP.SetAttribute("ZoneSettingsX", SecurityElement.Escape(x.colorvalues));

如果属性的名称包含 <>"'& 中的任何一个,您也必须像值一样对其进行转义。

注:

您必须删除当前使用旧代码创建的xml,因为它是无效的,加载时会导致异常。