0

I'm trying to call a method from a catch block but the xmlnode inside the method doesn't seem to work. I'm getting a null. If I call the same method from the try block it works.

var doc = new XmlDocument();

try
{

 doc.Load(f.FullPath);
// do some work 

}

 catch (Exception e)
 {
  if (e is XMLException)
  {
   checkXML(ref doc);
  }

public void checkXML(ref XmlDocument doc)
            {

                XmlNode xn = doc.SelectSingleNode("/BroadcastMonitor/Current");
                xn["name1"].InnerText = SecurityElement.Escape(xn["name1"].InnerText);
                xn["name2"].InnerText = SecurityElement.Escape(xn["name2"].InnerText); ;


            }

Now when the catch block calls method 'checkXML', i get xn as null. But if I execute the same from the 'try' block just to check, 'xn' has a value. 'doc' too has a value regardless of when called try or from catch block.

Why is this happening? Please help me understand.

EDIT

<BroadcastMonitor>
<updated>2014-10-17T07:56:30</updated>
<Name>TESTING</Name>
<Current>

    <artistName>اصاله&  نصرى</artistName>
    <albumName>شخصيه عنيده</albumName>
    <CategoryName>ARABIC & SONGS</CategoryName>

</Current>
</BroadcastMonitor>

Thank you.

user726720
  • 1,127
  • 7
  • 25
  • 59
  • 2
    Have you tried to debug your program and go step-by-step through your code to see what the content of the `doc` variable is in the exception code block? – keenthinker Oct 17 '14 at 05:26
  • yes I have done that, and as mentioned in my question. doc variable has value – user726720 Oct 17 '14 at 05:28
  • Does your code fails (=exception is raised) at `doc.Load(...)` or at `do some work`? – keenthinker Oct 17 '14 at 05:30
  • Try your code with a minimal XML structure. If it still does not work (so the problem is probably not an incorrect xml), please paste also the xml code in your question too. – keenthinker Oct 17 '14 at 05:34
  • @pasty: okay found the problem when it tries to load and there is a escape entity or something it would give me an xmlException, in that case the load is not complete and the elements are missing. thanks for the pointer.+1 for that. – user726720 Oct 17 '14 at 05:35

5 Answers5

1

Your xml contains an & character which is not a 'valid' xml character and must be escaped.

<CategoryName>ARABIC & SONGS</CategoryName>

So it's causing your Load() method to throw the exception.

What you should do is escape all the invalid characters in your xml string before passing them on to an xml parser like so

yourXmlString = XmlConvert.EncodeName(yourXmlString);

You can then pass the yourXmlString on to the parser like so

var xDoc = XDocument.Parse(yourXmlString);

or if you don't want to or can't use the XDocument class you will need to make sure you save the xml encoded so that the Load() method of the XmlDocument class will be reading a file that is properly encoded.

Note that XmlDocument and XDocument classes are not the same thing and have some significant differences. Method Parse(), if I remember correctly, is one of the advantages that XDocument has over XmlDocument.

EDIT :

You can read the xml file into a string using the File class

var yourXmlString = File.ReadAllText(filePath);
Alex
  • 1,110
  • 8
  • 15
  • Hey Alex, +1 for a detailed description. You solution looks good. But how do I get my xmlfile into yourxmlstring, using a streamreader or something. – user726720 Oct 17 '14 at 11:50
0

XmlDocument is a reference type... no need to pass it with ref.

And my guess is that its failing to load in the first place so doc is really null

Florian Schmidinger
  • 4,682
  • 2
  • 16
  • 28
0

It looks like this document is missing its xml declaration tag.

try:

XmlDocument doc = new XmlDocument;
using(StreamReader reader = new StreamReader(f.FullPath))
{
    doc.LoadXml(reader.ReadToEnd());
}
Florian Schmidinger
  • 4,682
  • 2
  • 16
  • 28
  • The xml declaration is there, it's just that I haven't added it here. The error is in , look at the & sign. This is illegal in XML. I just want to read the whole xml and fix the escaped entities. – user726720 Oct 17 '14 at 11:15
  • Well i would approach it with fixing the writing of these documents (to valid xml). otherwise you would need something like regex replacing and that is some task... – Florian Schmidinger Oct 17 '14 at 11:20
  • this is document is being writen by a software, I approached the support for the software, and they said this software is quite old and they will not spend time in fixing it's bugs anymore. So for me the only deed left is to fix it myself programmatically – user726720 Oct 17 '14 at 11:34
  • any clues on Regex would be much appreciated – user726720 Oct 17 '14 at 11:35
  • Its not that hard... i just need some time to figure it out.. we just need to find all inner node values an call html.encode on em... im currently not on my computer though – Florian Schmidinger Oct 17 '14 at 11:39
0

You can use System.IO.File.ReadAllText() to get all text from file into a string variable :

string invalidXml = System.IO.File.ReadAllText(f.FullPath);

For this particular XML, you can simply replace & with it's encoded version &amp; to make a valid XML string :

string validXml = invalidXml.Replace("&", "&amp;");
doc.LoadXml(validXml);
.....

Related question for reference : Reading XML with an "&" into C# XMLDocument Object

Community
  • 1
  • 1
har07
  • 88,338
  • 12
  • 84
  • 137
0

This would be my solution:

    private static Regex InnerValues = new Regex(@"(?<=<(.*?>)).*?(?=</\1)",RegexOptions.Compiled);

    private static XmlDocument LoadInvalidDocument(string path)
    {
        XmlDocument result = new XmlDocument();
        string content = File.ReadAllText(path);

        var matches = InnerValues.Matches(content);
        foreach (Match match in matches)
        {
            content = content.Replace(match.Value,  HttpUtility.HtmlEncode(match.Value));
        }
        result.LoadXml(content);
        return result;
    }
Florian Schmidinger
  • 4,682
  • 2
  • 16
  • 28