Reputation: 36048
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>
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();
}
}
}
}
Reading my algorithm might look confusing. I just need to place the content from the xml file into c#
Upvotes: 1
Views: 1031
Reputation: 63956
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>();
Upvotes: 0
Reputation: 59101
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.
Upvotes: 0
Reputation: 63065
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();
Upvotes: 2
Reputation: 36048
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);
}
UnhandledExeption solution looks much more simpler!
Upvotes: 0