Parsing XML in q (KX)

Viewed 393

Am trying to parse XML file in q. Am able to flatten the file but, further i could not extract the result. Below is the data set.

<breakfast_menu>
<food>
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>
   Two of our famous Belgian Waffles with plenty of real maple syrup
   </description>
    <calories>650</calories>
</food>
<food>
    <name>Strawberry Belgian Waffles</name>
    <price>$7.95</price>
    <description>
    Light Belgian waffles covered with strawberries and whipped cream
    </description>
    <calories>900</calories>
</food>
</breakfast_menu> ```

Below is the code i have tried so far.

file: read0 `$"File.xml"
file1: raze file
file2: enlist file2

Unable to parse the records further. Any suggestion will be helpful.

2 Answers

I wrote a small utility qxml previously using embedPy to extract XML data in to a kdb+ process.

q)\l qxml.q
q)menu:.qxml.read[`:menu.xml]
q)menu[`breakfast_menu;`food]
name                         price   description                             ..
-----------------------------------------------------------------------------..
"Belgian Waffles"            "$5.95" "Two of our famous Belgian Waffles with ..
"Strawberry Belgian Waffles" "$7.95" "Light Belgian waffles covered with stra..

Other options could be:

  • These C based projects xml and qexpat are also available on Github (I have not tested them).

  • kdb+ can natively parse JSON using .j.k if you can convert the file first.

For a pure q solution, you can try using this xml.q (translated from xml.k here). This is not a complete translation (xml.k can parse & encode XML, here I've only translated the parsing) and may not be as efficient or robust as other solutions using C/python, but it seems to allow parsing your example XML (saved as breakfast.xml):

q)b:.xml.dx raze read0`:breakfast.xml
q)b
`breakfast_menu
((`food;((`name;"Belgian Waffles");(`price;"$5.95");(`description;"Two of our..
q)b[0]
`breakfast_menu
q)b[1]
`food ((`name;"Belgian Waffles");(`price;"$5.95");(`description;"Two of our f..
`food ((`name;"Strawberry Belgian Waffles");(`price;"$7.95");(`description;"L..
q)      

Note that due to the indentation of lines etc. in the xml file there may be some extra padding in some of the strings after parsing. You can use trim to remove this e.g.

q)b:trim .xml.kx raze read0`:breakfast.xml
Related