I am trying to pull data from XML PList (Apple System Profiler) files, and read it into a memory database, and finally I want to turn it into something human-readable.
The problem is that the format seems to be very difficult to read in a consistent manner. I have gone over a few solutions already, but I haven’t found a solution yet that I found satisfying. I always end up having to hard code a lot of values, and end up having to many if-else/switch statements.
The format looks like this.
<plist>
<key>_system</key>
<array>
<dict>
<key>_cpu_type</key>
<string>Intel Core Duo</string>
</dict>
</array>
</plist>
Example file here.
After I have read (or during reading), I make use of an internal dictionary that I use to determine what type of information it is. For example, if the key is cpu_type I save the information accordingly.
A few examples that I have tried (simplified) to pull the information.
XmlTextReader reader = new
XmlTextReader("C:\\test.spx");
reader.XmlResolver = null;
reader.ReadStartElement("plist");
String key = String.Empty; String str
= String.Empty;
Int32 Index = 0;
while (reader.Read()) {
if (reader.LocalName == "key")
{
Index++;
key = reader.ReadString();
}
else if (reader.LocalName == "string")
{
str = reader.ReadString();
if (key != String.Empty)
{
dct.Add(Index, new KeyPair(key, str));
key = String.Empty;
}
}
}
Or something like this.
foreach (var d in xdoc.Root.Elements("plist"))
dict.Add(d.Element("key").Value,> d.Element("string").Value);
I found a framework, that I may be able to modify here.
Some more useful information
Mac OS X Information on the system profiler here.
Apple script used to parse the XML-files here.
Any advise or insight into this would be deeply appreciated.
my first thought for this is just to use XSLT (XSL transformations). i don’t know exactly what format you are looking for based on your answer in the above comments, but i think i got the gist at least. unless there’s something special you need that i didn’t think of, i believe XSLT is powerful enough to do everything you need, and no need for a bunch of complicated looping constructs.
if you’re not familiar, there’s a lot of good information on XSLT on w3schools (probably start at the intro: http://www.w3schools.com/xsl/xsl_intro.asp) and also wikipedia has a decent writeup on it (http://en.wikipedia.org/wiki/XSLT).
it always takes me a while to get the rules working the way i want; it’s a different way of thinking about this kind of transform and took me some getting used to. it’s necessary to have a decent understanding of XPATH as well. i am constantly having to refer to both the XSLT spec (http://www.w3.org/TR/xslt) and the XPATH spec (http://www.w3.org/TR/xpath/) since i’ve only had a small amount of experience with it, probably once you have worked with it a while it goes more smoothly.
anyway, i have an app i wrote previously for playing around with these translations. it’s a C# application with three textboxes: one for the XSLT, one for the source, and one for the output. i spent a few (okay, many) hours trying to get a first cut of an XSLT that would process your sample data, to get an idea of how hard it would be and what the structure of the transform would be. i think i finally figured out pretty much what was needed, but since i don’t know exactly what format you need, i stopped there.
here’s a link to the sample transformed output: http://pastebin.com/SMFxUdDK.
following is all the code to actually do the transform, included in a form that you can use to develop as you go. it’s not fancy but it has worked well for me. the “heavy lifting” is all done in the “btnTransform_Click()” handler, plus i have implemented an XmlStringWriter to make it easy to output things the way i want. the main bit of the work here is just in coming up with the XSLT directives, the actual transform is fairly well handled for you in the .NET XslCompiledTransform class. however, i figured i had spent enough time figuring out all the little details on it when i wrote it that it was worth giving a working example…
be aware i changed a couple of occurrences of a namespace here on-the-fly, and also added some light comments to the XSLT, so if there are issues let me know and i will correct them.
so, with no further adieu: 😉
the XSLT file:
a little helper class i made (
XmlStringWriter.cs) :the windows forms designer class (
frmXSLTTest.Designer.cs)the form class (
frmXSLTTest.cs):