XElement with LINQ 在特定节点后添加节点

XElement with LINQ add node after specific node

我知道了 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">
              <ColorPool Class="Parameter" DescriptiveName="Colors for the job" Status="Available">
                <InkZoneProfile Separation="PANTONE 647 C" ZoneSettingsX="0 0,003 " />
              </ColorPool>
            </InkZoneProfile>
          </InkZoneProfile>
        </InkZoneProfile>
      </InkZoneProfile>
    </ResourceCmdParams>
  </Command>
</JMF>

我正在尝试使用 XElement 和 Linq 在特定 node() 之后添加一个节点。但是我的 LINQ 查询总是 returns me null。 试过这个:

            XElement InkZonePath = XmlDoc.Element("JMF").Elements("InkZoneProfile").Where(z => z.Element("InkZoneProfile").Attribute("Side").Value == "Front").SingleOrDefault();

还有这个:

            XmlDoc.Element("JMF")
                   .Elements("InkZoneProfile").Where(InkZoneProfile => InkZoneProfile.Attribute("Side")
                   .Value == "Front").FirstOrDefault().AddAfterSelf(new XElement("InkZoneProfile",
                   new XAttribute("Separation", x.colorname),
                   new XAttribute("ZoneSettingsX", x.colorvalues)));

我根据这些示例构建了此查询:

Select XElement where child element has a value

LINQ-to-XML XElement query NULL

但它没有按预期工作。 LINQ 查询有什么问题?从我读过的内容来看,它应该可以工作(从逻辑上看我可以理解它的表达方式)。

谢谢

EDIT-1:整个 writexml 方法

public void writexml(xmldatalist XMLList, variables GlobalVars)
        {

            XmlWriterSettings settings = new XmlWriterSettings
            {
                Indent = true,
                IndentChars = "\t",
                NewLineChars = Environment.NewLine,
                NewLineHandling = NewLineHandling.Replace,
                Encoding = new UTF8Encoding(false)
            };

            string DesktopFolder = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            string FileExtension = ".xml";
            string PathString = Path.Combine(DesktopFolder, "XML");
            System.IO.Directory.CreateDirectory(PathString);


            foreach (List<xmldata> i in XMLList.XMLArrayList)
            {
                int m = 0;
                foreach (var x in i)
                {

                    string XMLFilename = System.IO.Path.GetFileNameWithoutExtension(x.xml_filename);                    
                    GlobalVars.FullPath = Path.Combine(PathString, XMLFilename + FileExtension);


                    if (!File.Exists(GlobalVars.FullPath))
                    {
                        XDocument doc = new XDocument(
                         new XDeclaration("1.0", "utf-8", "yes"),

                         new XElement("JMF",
                             new XAttribute("SenderID", "InkZone-Controller"),
                             new XAttribute("Version", "1.2"),
                        new XElement("Command",
                             new XAttribute("ID", "cmd.00695"),
                             new XAttribute("Type", "Resource"),
                        new XElement("ResourceCmdParams",
                            new XAttribute("ResourceName", "InkZoneProfile"),
                            new XAttribute("JobID", "K_41"),
                        new XElement("InkZoneProfile",
                            new XAttribute("ID", "r0013"),
                            new XAttribute("Class", "Parameter"),
                            new XAttribute("Locked", "False"),
                            new XAttribute("Status", "Available"),
                            new XAttribute("PartIDKeys", "SignatureName SheetName Side Separation"),
                            new XAttribute("DescriptiveName", "Schieberwerte von DI"),
                            new XAttribute("ZoneWidth", "32"),
                        new XElement("InkZoneProfile",
                            new XAttribute("SignatureName", "SIG1"),
                        new XElement("InkZoneProfile",
                            new XAttribute("Locked", "false"),
                            new XAttribute("SheetName", "S1"),
                        new XElement("InkZoneProfile",
                            new XAttribute("Side", "Front"),
                        new XElement("ColorPoolClass",
                            new XAttribute("Class", "Parameter"),
                            new XAttribute("DescriptiveName", "Colors for the job"),
                            new XAttribute("Status", "Available")
                            )))))))));
                        doc.Save(GlobalVars.FullPath);

                        XDocument XmlDoc = new XDocument();
                        XmlDoc = XDocument.Load(GlobalVars.FullPath);
                        XElement InkZonePath = XmlDoc.Root.Descendants("InkZoneProfile").Where(z => (string)z.Attribute("Side") == "Front").SingleOrDefault();

                        if (InkZonePath != null)
                        {
                            InkZonePath.AddAfterSelf(new XElement("InkZoneProfile",
                                   new XAttribute("Separation", x.colorname),
                                   new XAttribute("ZoneSettingsX", x.colorvalues)));

                        }
                        XmlDoc.Save(GlobalVars.FullPath);

                        }//Closing !FileExists
                    }//Closing inner foreach


            }//Closing outer foreach


        }//Closing writexml method

您需要使用 Descendants 方法 Elements:

XElement InkZonePath = XmlDoc.Root.Descendants("InkZoneProfile").Where(z => (string)z.Attribute("Side") == "Front").SingleOrDefault();

if(InkZonePath !=null)
   InkZonePath.AddAfterSelf(new XElement("InkZoneProfile",
               new XAttribute("Separation", x.colorname),
               new XAttribute("ZoneSettingsX", x.colorvalues)));

您可以改用后代。

var node  = XmlDoc.Descendants("InkZoneProfile").Where(x=> x.Attribute("Side") !=null && x.Attribute("Side").Value == "Front").FirstorDefault();

您当前代码的问题在于:Element("JMF").Elements("InkZoneProfile") 因为 InkZoneProfile 不是 JMF 的直接子代,所以不会 return 任何东西。请改用 Descendants

Check difference between Elements & Descendants.

这应该会给你正确的结果:-

 XElement InkZonePath = xdoc.Element("JMF").Descendants("InkZoneProfile")
                            .SingleOrDefault(z => (string)z.Attribute("Side") == "Front")

在此之后,您可以使用 AddAfterSelf 添加您想要添加的任何节点。另请注意,我在这里使用了 SingleOrDefault,但如果您有多个匹配节点,您可能会遇到异常,在这种情况下,请考虑使用 FirstOrDefault.

更新:

添加新节点:-

if (InkZonePath != null)
{
    InkZonePath.AddAfterSelf(new XElement("InkZoneProfile",
                             new XAttribute("Separation", "Test"),
                             new XAttribute("ZoneSettingsX", "Test2")));
}
//Save XDocument                              
xdoc.Save(@"C:\Foo.xml");