Search code examples
c#xmlxmldocumentxelementselectsinglenode

What is wrong with this file or code?


What is happening \ what is the difference ? I'm trying to return a specific node from an XML File.

XML File:

  <?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>

Code:

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

The var parent returns me null. I've debugged , and root and xmlDoc have on their inner text the XML Content. But, a test made here(made by user @har07 , on the previous question: SelectSingleNode returns null even with namespace managing Worked without problems. https://dotnetfiddle.net/vJ8h9S

What is the difference between those two ? They follow the same code basically, but one works and other doesn't.
When debugging i've found that root.InnerXml has the contents loaded on itself (same as XmlDoc.InnerXml ). But InnerXml doesn't implement a method to SelectSingleNode. I believe that if i save it to a string i'll probably lose indentation and etc.

Can someone tell me what is the difference or what is wrong ? Thanks ! XML Sample: https://drive.google.com/file/d/0BwU9_GrFRYrTUFhMYWk5blhhZWM/view?usp=sharing


Solution

  • SetAttribute don't auto escape string for you. Therefore it make your XML file invalid.

    From MSDN about 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

    Find in your code all line contain SetAttribute and use SecurityElement.Escape to escape the value.

    For example: Change these lines:

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

    To:

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

    If an attribute have name contains any of <>"'& you also have to escape it like the value.

    Note:

    You have to delete current xmls you create used the old code, because it is invalid, when you load it will cause exception.