Parsing SymbolicXML

An XML Example Using Mathematica 4.2

Once we have an XML file, we can use Mathematica to read the file as SymbolicXML.  In this case, the data set is an XML form of the Ritter Catalog of Cataclysmic Variable Stars (Ritter, H., & Kolb, U., 1998, A&AS, 129, 83).  This XML file was created using Mathematica 4.2 to modify the original row-column format of the data set (refer to the notebook entitled DataToXML.nb).  You will probably need to modify the path to the file to reflect its location at your end.

newdata = Import["ritterxml.xml"];

We can view the data in SymbolicXML format as follows.

newdata

Now that we have a SymbolicXML expression, we can parse the expression for any data we might want.  Below is a series of parsing functions that look for XMLElements with particular names and/or properties and then extract the data into Mathematica's list format.

GetNames[xml_] := 
        Cases[xml, XMLElement["NAME", {}, {name_}] -> name, 
          Infinity];
GetMR[xml_] := 
        Cases[xml, 
          XMLElement["MASSRATIO", {}, {mr_}] -> ToExpression[mr], 
          Infinity];
GetMag1[xml_] := 
        Cases[xml, XMLElement["MAG1", {}, {mag1_}] -> mag1, 
          Infinity];
\(\(GetNameMRPair[xml_] := 
        Cases[xml, 
          XMLElement["OBJECT", _, {___, 
                XMLElement["NAME", _, {name_}], ___, 
                XMLElement["MASSRATIO", {}, {mr_}], ___}] :> {name, ToExpression[mr]}, Infinity];\)\)
\(\(GetNameMag1Pair[xml_] := 
        Cases[xml, 
          XMLElement["OBJECT", _, {___, 
                XMLElement["NAME", _, {name_}], ___, 
                XMLElement["MAG1", {}, {mag1_}], ___}] :> {name, ToExpression[mag1]}, Infinity];\)\)
\(\(GetMag1MR[xml_] := 
        Cases[xml, 
          XMLElement["OBJECT", _, {___, 
                XMLElement["MAG1", _, {mag1_}], ___, 
                XMLElement["MASSRATIO", {}, {mr_}], ___}] :> {ToExpression[mr], ToExpression[mag1]}, Infinity];\)\)
\(\(GetOrbPerMR[xml_] := 
        Cases[xml, 
          XMLElement["OBJECT", _, {___, 
                XMLElement["ORBPER", _, {orb_}], ___, 
                XMLElement["MASSRATIO", {}, {mr_}], ___}] :> {ToExpression[orb]*24, ToExpression[mr]}, Infinity];\)\)
\(\(GetNameMaglimitedPair[xml_] := 
        Cases[xml, 
          XMLElement["OBJECT", _, {___, 
                XMLElement["NAME", _, {name_}], ___, 
                XMLElement["MAG1", {}, {mag1_}], ___}] :> {name, ToExpression[mag1]}, Infinity];\)\)

Here's an example of using one of the parsing functions that was written.  In this case, we are going to extract a list of pairs of data.  Each pair consists of the orbital period and the mass ratio.  In addition, several parsing functions are defined that allow the data to be divided into two groups: the first have orbital periods less than 2.1 hours and the second have orbital periods greater than 2.1 hours.

mydata = GetOrbPerMR[newdata];
myless[num_] := num < 2.1;
mygreater[num_] := num > 2.1;
firstset = 
        Cases[mydata, {x_?myless, y_} :> {x, y}];
secset = 
        Cases[mydata, {x_?mygreater, y_} :> {x, 
              y}];

With the data now extracted and organized, we can plot the data.

\(\(Module[{a, b}, 
        a = ListPlot[firstset, DisplayFunction -> Identity, 
            PlotStyle -> {RGBColor[1, 0, 0], 
                PointSize[0.011]}]; 
b = 
          ListPlot[secset, DisplayFunction -> Identity, 
            PlotStyle -> {RGBColor[0, 0, 1], 
                PointSize[0.011]}]; 
Show[a, b, 
          DisplayFunction -> $DisplayFunction, Frame -> True, 
          FrameLabel -> {"Orbital Period (hours)", \*""Mass Ratio ((Subscript[M, 1])/(Subscript[M, 2]))""}, ImageSize -> 550, 
          TextStyle -> {FontFamily -> "Times"}]];\)\)

Of course it is easy to perform a much more simple analysis of the data, such as getting the number of elements that have particular properties.  Below, we are able to get the number of named objects in the data set followed by the number of entries with the mass ratio specified.

Length@GetNames[newdata]

Length@GetMR[newdata]