4

( Part of ) a matrix representation of the objects I work with is the following:

 {
 {1, A,{100,  20, 30},10},
 {2, B,{100}, 0},
 {3, X,{120,20},0},
 {4, C,{},11}
 }

I want to store this data externally in XML Format as follows

<data>
<row key="1" val1="A" val2="10"> <occ>100</occ><occ>20</occ><occ>30</occ></row>
<row key="2" val1="B" val2="0"><occ>100</occ></row>
<row key="3" val1="X" val2="0"><occ>120</occ><occ>20</occ></row>
<row key="4" val1="C" val2="11"></row>
</data>

I am looking for an example on how to:

- transfer the the matrix to XML ( which Mathematica commands ? )

- parse the XML string back to matrix format after having imported the XML file.

Community
  • 1
  • 1
nilo de roock
  • 4,077
  • 4
  • 34
  • 62

1 Answers1

5

Here we import your data as symbolic XML:

In[50]:= xml = Import["C:\\Temp\\matrixData.xml"]

Out[50]= XMLObject["Document"][{}, 
 XMLElement["data", {}, 
 {XMLElement["row", {"key" -> "1", "val1" -> "A", "val2" -> "10"}, 
      {XMLElement["occ", {}, {"100"}], XMLElement["occ", {}, {"20"}], 
        XMLElement["occ", {}, {"30"}]}], 
  XMLElement["row", {"key" -> "2", "val1" -> "B", "val2" -> "0"},
      {XMLElement["occ", {}, {"100"}]}],
  XMLElement[ "row", {"key" -> "3", "val1" -> "X","val2" -> "0"}, 
      {XMLElement["occ", {}, {"120"}], XMLElement["occ", {}, {"20"}]}], 
  XMLElement["row", {"key" -> "4", "val1" -> "C", "val2" -> "11"}, {}]}], {}]

Here we parse into a matrix:

In[51]:= matr = 
 xml /. XMLObject["Document"][{}, data_, _] :> data /. 
     XMLElement["data", _, children_] :> children /. 
         XMLElement["row", attrs_, vals_] :> {"key" /. attrs, 
             "val1" /. attrs, vals /. XMLElement["occ", _, {val_}] :> val, 
             "val2" /. attrs} /. s_String :> ToExpression[s]

 Out[51]= {{1, A, {100, 20, 30}, 10}, {2, B, {100}, 0}, {3,X, {120, 20}, 0}, {4, C, {}, 11}}

The code is short and economical due to the use of rule-within-a-rule technique. I discuss it here. One nice application of this technique can be found here.

Here is the reverse:

XMLObject["Document"][{}, XMLElement["data", {},
  Replace[matr, {key_, val1_, vals_List, val2_} :>
      XMLElement[ "row", {"key" -> ToString[key], "val1" -> ToString[val1], 
          "val2" -> ToString[val2]},
             XMLElement["occ", {}, {ToString[#]}] & /@ vals], {1}]], {}]

I do not show the result but it is the same as the imported symbolic XML. You can call Export with this symbolic XML and it will know how to handle it.

Community
  • 1
  • 1
Leonid Shifrin
  • 22,449
  • 4
  • 68
  • 100
  • @ndroock1 Thanks for the accept. By the way, when parsing from XMK to matrix, I assumed that you want `A`,`B`, etc as symbols. If you want them as strings, change the rule `s_String :> ToExpression[s]` to `s_String/;StringMatchQ[s,NumberString] :> ToExpression[s]`, so that only numbers get parsed. – Leonid Shifrin Jul 06 '11 at 18:40