-3

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

Community
  • 1
  • 1
Pablo Costa
  • 125
  • 4
  • 14
  • 1
    Maybe that's because of `&` characters in your XML. `&` is [special character](http://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents) in XML which need to be escaped. In the demo I linked to, I have removed all `&` characters to make it work, otherwise `LoadXml()` will throw exception – har07 Feb 28 '16 at 01:03
  • 1
    @Pablo it is an error in the code you create this line: ` – NoName Feb 28 '16 at 01:49
  • @Sakura check the edit – Pablo Costa Feb 28 '16 at 02:08
  • Sorry it looks horrible. I'm on my phone – Pablo Costa Feb 28 '16 at 02:17

1 Answers1

1

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.

NoName
  • 7,940
  • 13
  • 56
  • 108
  • I got it. But all my attributes defined using XMLWriter have double quotes. Not only those two. I'm trying to figure out a way to replace them. I believe that if i convert to string, replace, then convert back to XML i may lose identing. – Pablo Costa Feb 28 '16 at 15:23
  • 1
    @PabloCosta Of course all attributes have double quotes around the value. It is the standar. the synstax of an attributes is `name="value"` – NoName Feb 28 '16 at 15:27
  • Yeah i know it. But the dotnetfiddle sample worked without using double quotes. Also i may have characaters like & like an attribute value. The main trouble is that i can't get the specific node i'm looking for. – Pablo Costa Feb 28 '16 at 15:31
  • 1
    What do you mean by don't have double quote + have `&` char? Do you mean you want a xml note like this `` – NoName Feb 28 '16 at 15:35
  • No. If you see the dontnetfiddle sample , it has no double quotes on it(only single quotes). Like . And i believe thats why i can't read the xml node i'm looking for. – Pablo Costa Feb 28 '16 at 15:38
  • 1
    Could you post the XML sample you mentioned? – NoName Feb 28 '16 at 15:44
  • please check my edit. I added the dotnetfiddle sample and the XML sample. – Pablo Costa Feb 28 '16 at 15:51
  • 1
    Ok I see. You don't have to worry about single quote or double quotes. It is boundary of the value. What I say is what characters inside that boundary. Follow my suggest above and you will have valid XML file. Also, if an attribute contains any of following string, it still OK: `<`, `>`, `"`, `'`, `&` – NoName Feb 28 '16 at 16:02
  • I already followed your suggestion. But it didn't changed the scenario. The var parent is still null. And i need it to reach the SpecificSingle node. I have: var parent = xmlDoc.SelectSingleNode (xpath) - but this parent always receives a null value (meaning xpath didn't worked). – Pablo Costa Feb 28 '16 at 16:08
  • 1
    OK. post the `C:\\test\\test.xml` file here (the real current xml) I'll point what you did wrong. – NoName Feb 28 '16 at 16:16
  • Please check the edited post. I added the generated XML file. – Pablo Costa Feb 28 '16 at 16:28
  • 1
    You'll easily noticed that in your XML a node is inserted wrong position. In the NetFiddle example, your XML have 5 level of `InkZoneProfile`, but your XML you create only have 4 level (one other jump wrong position). That why it is null. – NoName Feb 28 '16 at 16:56
  • The last InkZoneProfile is the one inserted. Others were written before. I'm trying to insert just after . That's why the node goes 4 level only – Pablo Costa Feb 28 '16 at 16:58
  • The JSFD file use `ResourceCmdParams`, but your file use `ResourceCMDParams` (cmd vs CMD) – NoName Feb 28 '16 at 17:14
  • 1
    Change this line: `xmlDoc.DocumentElement.AppendChild(IZP);` to `parent.AppendChild(IZP);` – NoName Feb 28 '16 at 17:19
  • I can't say how much i'm happy for it working. But also i'm embarassed because the main problem was CMD vs Cmd. Other details were wrong because i changed the code tons of times in order to make it work. Please post it as an answer so i may mark as acceped. Thanks a lot, i really appreciate your help and effort. – Pablo Costa Feb 28 '16 at 17:22