简体   繁体   English

具有LINQ的XElement在特定节点之后添加节点

[英]XElement with LINQ add node after specific node

I've got this 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">
              <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>

I'm trying to add a node after a specific node() , using XElement and Linq. 我正在尝试使用XElement和Linq在特定节点()之后添加节点。 But my LINQ query always returns me null. 但我的LINQ查询总是返回null。 Tried this: 试过这个:

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

And this: 和这个:

            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)));

I've built this queries following those examples: 我按照这些示例构建了这些查询:

Select XElement where child element has a value 选择子元素具有值的XElement

Insert XElements after a specific node 在特定节点之后插入XElements

LINQ-to-XML XElement query NULL LINQ-to-XML XElement查询NULL

But it didn't worked as expected. 但它没有按预期工作。 What is wrong with the LINQ Query ? LINQ查询有什么问题? From what i've read it should work (logically reading the expression i can understand it). 从我读过它应该工作(逻辑上阅读我能理解的表达)。

Thanks 谢谢

EDIT-1: Entire writexml Method 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

You need to use Descendants method instead Elements : 您需要使用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)));

你可以用Descendants代替。

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

The problem with your current code is here : Element("JMF").Elements("InkZoneProfile") Since InkZoneProfile is not a direct child of JMF it will not return anything. 您当前代码的问题在于: Element("JMF").Elements("InkZoneProfile")由于InkZoneProfile不是JMF的直接子代,因此它不会返回任何内容。 Use Descendants instead. 请改用Descendants

Check difference between Elements & Descendants. 检查Elements和Descendants之间的区别。

This should give you correct result:- 这应该给你正确的结果: -

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

After this you can add whatever node you want to add using AddAfterSelf . 在此之后,您可以使用AddAfterSelf添加要添加的节点。 Also note I have used SingleOrDefault here, but you may get exception if you have multiple matching nodes with this, In that case consider using FirstOrDefault . 另请注意,我在这里使用过SingleOrDefault ,但是如果你有多个匹配的节点,你可能会遇到异常,在这种情况下考虑使用FirstOrDefault

Update: 更新:

To add new node:- 要添加新节点: -

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM