1

I don't understand why I am getting errors when parsing an xml file. I have a class:

class FileSignature
{
    public string signature{ get; set; }
    public string[] extensions{ get; set; }
    public string description { get; set; }
}

I basically need to populate a list of FileSignature List<FileSignature> by parsing an xml file: the xml file looks like:

<?xml version="1.0" encoding="utf-8" ?>

<Files>
  <File>
    <Signature>482B424544562050726F6475637473204C6963656E7365204B65792046696C650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A</Signature>
    <Extension>KEY</Extension>
    <Description>AviraProductKey</Description>
  </File>
  <File>
    <Signature>FFFE570069006E0064006F0077007300200052006500670069007300740072007900200045006400690074006F0072002000560065007200730069006F006E00200035002E0030003000</Signature>
    <Extension>REG</Extension>
    <Description>RegistryDataFile5.00</Description>
  </File>
  <File>
    <Signature>41565020416E7469766972616C2044617461626173652E202863294B6173706572736B79204C616220313939372D32</Signature>
    <Extension>AVC</Extension>
    <Description>KasperskyAnti-VirusDatabase</Description>
  </File>
  <File>
    <Signature>00000002FFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000</Signature>
    <Extension>MAC</Extension>
    <Description>MacPaintBitmapGraphic</Description>
  </File>      
  <File>
    <Signature>52494646????????415649204C495354</Signature>
    <Extension>AVI</Extension>
    <Description>WindowsAudioVideoInterleave</Description>
  </File>      
  <File>
    <Signature>464C5601</Signature>
    <Extension>FLV</Extension>
    <Description>FlashVideo</Description>
  </File>
  <File>
    <Signature>1</Signature>
    <Extension>MPG</Extension>
    <Description>MPEGVideoFile</Description>
  </File>
  <File>
    <Signature>465753</Signature>
    <Extension>SWF</Extension>
    <Description>MacromediaFlashFormat</Description>
  </File>
  <File>
    <Signature>435753</Signature>
    <Extension>SWF</Extension>
    <Description>ShockwaveFlash(v5+)</Description>
  </File>
  <File>
    <Signature>FFD8FF</Signature>
    <Extension>JPG</Extension>
    <Description>JPEG/JIFFImage</Description>
  </File>
  <File>
    <Signature>1F8B08</Signature>
    <Extension>GZ</Extension>
    <Description>GZipCompressedArchive</Description>
  </File>
  <File>
    <Signature>1F9D90</Signature>
    <Extension>Z</Extension>
    <Description>UNIXCompressedArchive</Description>
  </File>
  <File>
    <Signature>494433</Signature>
    <Extension>MP3</Extension>
    <Description>MP3Audio</Description>
  </File>
  <File>
    <Signature>FFFB</Signature>
    <Extension>MP3</Extension>
    <Description>MP3Audio</Description>
  </File>
  <File>
    <Signature>FFFA</Signature>
    <Extension>MP3</Extension>
    <Description>MP3Audio</Description>
  </File>
  <File>
    <Signature>4D5A</Signature>
    <Extension>EXE|COM|DLL|SYS</Extension>
    <Description>WindowsExecutable</Description>
  </File>
  <File>
    <Signature>424D</Signature>
    <Extension>BMP</Extension>
    <Description>WindowsOS/2BitmapGraphics</Description>
  </File>
  <File>
    <Signature>9501</Signature>
    <Extension>SKR</Extension>
    <Description>PGPPrivateKeyring</Description>
  </File>
  <File>
    <Signature>9901</Signature>
    <Extension>PKR</Extension>
    <Description>PGPPublicKeyring</Description>
  </File>

</Files>

and I don't understand why my code is not working. I don't want the xml file to be in exact order. In other words I want to treat:

  <File>
    <Signature>4D5A</Signature>
    <Extension>EXE|COM|DLL|SYS</Extension>
    <Description>WindowsExecutable</Description>
  </File>

just like:

 <File>
    <Description>WindowsExecutable</Description>        
    <Extension>EXE|COM|DLL|SYS</Extension>
    <Signature>4D5A</Signature>
  </File>

and my code for parsing that xml file is:

class FileSignature
{
    public string signature;
    public string[] extensions;
    public string description { get; set; }
}

// Constructor here is where I start implementing the algorithm
class FileSignatures
{
    public static List<FileSignature> Files;

    public FileSignatures()
    {
        // list where to place the files
        Files = new List<FileSignature>();


        // that is the path where the xml is located
        XmlTextReader reader = new XmlTextReader(@"A:\Users\Tono\Desktop\SaveContentFromCache\SaveContentFromCache\FileSignatures.xml");


        while (reader.Read())
        {
            // if we find a file element then
            if (reader.Name.ToString().ToLower().Equals("file"))
            {
                // place that entire xml in a string
                string temp = reader.ReadInnerXml().ToString();

                // Create an XmlReader
                XmlReader readerOfParent = XmlReader.Create(new StringReader(temp));

                FileSignature f = new FileSignature();
                while (readerOfParent.Read()) // !!!!!!!!!!!! here is where I get the error 
                {
                    if (readerOfParent.Name.ToString().ToLower().Contains("signature"))
                        f.signature = readerOfParent.ReadInnerXml().ToString();

                    if (readerOfParent.Name.ToString().ToLower().Contains("extension"))
                        f.extensions = readerOfParent.ReadInnerXml().ToString().Split('|');

                    if (readerOfParent.Name.ToString().ToLower().Contains("description"))
                        f.description = readerOfParent.ReadInnerXml().ToString();
                }

                Files.Add(f);
                readerOfParent.Close();


            }

        }
    }

}

EDIT

Reading my algorithm might look confusing. I just need to place the content from the xml file into c#

1
  • Which version of .NET are you using? Commented Nov 5, 2011 at 5:09

4 Answers 4

2
XDocument xdoc= XDocument.Load(@"A:\Users\Tono\Desktop\SaveContentFromCache\SaveContentFromCache\FileSignatures.xml");

List<FileSignature> fileSignatures = (from file in xdoc.Element("Files").Elements("File")
         select new FileSignature
         {
           signature= file.Element("Signature").Value,
           extensions= file.Element("Extension").Value.Split('|'),
           description = file.Element("Description").Value
         }).ToList();
Sign up to request clarification or add additional context in comments.

2 Comments

I am not able to use xdoc.Element I am instantiating xdoc from System.Xml.Linq.XDocument . Maybe I need to add a reference to my wpf application. Thanks a lot for the help. If I new I could use linq I would have give it another try
@TonoNam try now. it should be Elements. i tested with your xml file and this is working fine.
0

I was working in a solution meanwhile waiting for an answer. I guess I should had tried longer. anyways here is what I worked out:

// list where to place the files
Files = new List<FileSignature>();

//Load xml
XDocument xdoc = XDocument.Load(@"A:\Users\Tono\Desktop\SaveContentFromCache\SaveContentFromCache\FileSignatures.xml");

//Run query
var files = from elements in xdoc.Descendants("File")
           select new { 
               Children = elements.Descendants()
           };

//Loop through results
foreach (var elem in files)
{
    FileSignature f = new FileSignature();
    foreach (var lv2 in elem.Children)
    {
        if (lv2.Name.ToString().ToUpper().Contains("SIGNATURE"))
            f.signature = lv2.Value.ToString();
        else if (lv2.Name.ToString().ToUpper().Contains("DESCRIPTION"))
            f.description = lv2.Value.ToString();
        else if (lv2.Name.ToString().ToUpper().Contains("EXTENSION"))
            f.extensions = lv2.Value.ToString().Split('|');              
    }
    Files.Add(f);
}

edit

UnhandledExeption solution looks much more simpler!

Comments

0

I worked on a different solution using XML serialization. It isn't quite as clean for a one-off reading as the Linq to XML example. But it will work in older code, and will be more easily embedded if you have more XML or a bigger object tree than just this list. It also supports both read and write operations.

using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

public class FileSignature
{
    public override string ToString()
    {
        return string.Format("Description: '{0}', Extensions: '{1}', Signature: '{2}'"
            , Description
            , string.Join("|", (Extensions ?? new string[0]))
            , Signature
            );
    }

    public string Signature { get; set; }

    [XmlIgnore]
    public string[] Extensions { get; set; }

    [XmlElement(ElementName="Extension")]
    [System.ComponentModel.EditorBrowsable(
        System.ComponentModel.EditorBrowsableState.Never)]
    public string ExtensionsSerialized
    {
        get
        {
            return Extensions == null
                ? ""
                : string.Join("|", Extensions);
        }
        set
        {
            System.Console.WriteLine("Value: {0}", value);
            Extensions = value.Split('|');
        }
    }

    public string Description { get; set; }
}

[XmlRoot("Files")]
public class FileSignatureCollection
{
    public FileSignatureCollection()
    {
        Items = new List<FileSignature>();
    }

    [XmlElement("File")]
    public List<FileSignature> Items { get; set; }
}

class Program
{
    static void Main()
    {
        using(var xml = File.OpenRead("test.xml"))
        {
            var serializer = new XmlSerializer(typeof(FileSignatureCollection));
            var signatures = (FileSignatureCollection)serializer.Deserialize(xml);

            foreach(var sig in signatures.Items)
            {
                System.Console.WriteLine(sig);
            }
        }
    }
}

If this list is embedded in a bigger type, than you can forego the FileSignatureCollection wrapper.

Comments

0
string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?><Files>  <File>    <Signature>482B424544562050726F6475637473204C6963656E7365204B65792046696C650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001A</Signature>    <Extension>KEY</Extension>    <Description>AviraProductKey</Description>  </File>  <File>    <Signature>FFFE570069006E0064006F0077007300200052006500670069007300740072007900200045006400690074006F0072002000560065007200730069006F006E00200035002E0030003000</Signature>    <Extension>REG</Extension>    <Description>RegistryDataFile5.00</Description>  </File>  <File>    <Signature>41565020416E7469766972616C2044617461626173652E202863294B6173706572736B79204C616220313939372D32</Signature>    <Extension>AVC</Extension>    <Description>KasperskyAnti-VirusDatabase</Description>  </File>  <File>    <Signature>00000002FFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000</Signature>    <Extension>MAC</Extension>    <Description>MacPaintBitmapGraphic</Description>  </File>        <File>    <Signature>52494646????????415649204C495354</Signature>    <Extension>AVI</Extension>    <Description>WindowsAudioVideoInterleave</Description>  </File>        <File>    <Signature>464C5601</Signature>    <Extension>FLV</Extension>    <Description>FlashVideo</Description>  </File>  <File>    <Signature>1</Signature>    <Extension>MPG</Extension>    <Description>MPEGVideoFile</Description>  </File>  <File>    <Signature>465753</Signature>    <Extension>SWF</Extension>    <Description>MacromediaFlashFormat</Description>  </File>  <File>    <Signature>435753</Signature>    <Extension>SWF</Extension>    <Description>ShockwaveFlash(v5+)</Description>  </File>  <File>    <Signature>FFD8FF</Signature>    <Extension>JPG</Extension>    <Description>JPEG/JIFFImage</Description>  </File>  <File>    <Signature>1F8B08</Signature>    <Extension>GZ</Extension>    <Description>GZipCompressedArchive</Description>  </File>  <File>    <Signature>1F9D90</Signature>    <Extension>Z</Extension>    <Description>UNIXCompressedArchive</Description>  </File>  <File>    <Signature>494433</Signature>    <Extension>MP3</Extension>    <Description>MP3Audio</Description>  </File>  <File>    <Signature>FFFB</Signature>    <Extension>MP3</Extension>    <Description>MP3Audio</Description>  </File>  <File>    <Signature>FFFA</Signature>    <Extension>MP3</Extension>    <Description>MP3Audio</Description>  </File>  <File>    <Signature>4D5A</Signature>    <Extension>EXE|COM|DLL|SYS</Extension>    <Description>WindowsExecutable</Description>  </File>  <File>    <Signature>424D</Signature>    <Extension>BMP</Extension>    <Description>WindowsOS/2BitmapGraphics</Description>  </File>  <File>    <Signature>9501</Signature>    <Extension>SKR</Extension>    <Description>PGPPrivateKeyring</Description>  </File>  <File>    <Signature>9901</Signature>    <Extension>PKR</Extension>    <Description>PGPPublicKeyring</Description>  </File></Files>";

 XDocument doc = XDocument.Parse(xml);
 List<FileSignature> files = (
                     from c in doc.Descendants("File")
                     select new FileSignature 
                     { description=c.Descendants("Description").First().Value,
                       extensions =c.Descendants("Extension").First().Value.Split('|')  ,
                       signature=c.Descendants("Signature").First().Value }
                      ).ToList();

Will convert your XML string to a List<FileSignature>();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.