Hi Wolfgang,

Thank you so much for your help with this. Your solution is exactly what I'm looking for.

Regards

Mark



On 06/07/10 23:02, Wolfgang Meyer wrote:
Hi Mark,

the following should work, as long as the names of the attributes and
child elements of an element are all different to each other. If this
is not the case, the call to List.toRecord will fail.

Cheers,
   Wolfgang


declare
   [XMLParser] = {Module.link ['x-oz://system/xml/Parser.ozf']}
   Parser = {New XMLParser.parser init}

   %% Converts an XML document (as returned by the system XML parser)
   %% to a record.
   %% Prerequisite: no two child elements with the same name; attributes have
   %% different names than child elements.
   fun {Deserialize XmlDoc}
      case XmlDoc of element(attributes:As children:Cs name:N ...) then
         Xs = {Append As {CombineTexts Cs}}
         fun {GetName X} X.name end
         fun {MakePair A B} A#B end
      in
         {List.toRecord N
          {List.zip {Map Xs GetName} {Map Xs Deserialize}  MakePair}}
      [] string(Text ...) then Text
      [] attribute(value:Val ...) then Val
      end
   end

   %% Combines all text elements in the list of child elements Cs
   %% to one string element; returns the new list of child elements
    fun {CombineTexts Cs}
       fun {IsText C} {Label C} == text end
       fun {GetData text(data:D)} D end
       Texts NonTexts
       {List.partition Cs IsText ?Texts ?NonTexts}
       AppendedTexts = {FoldL {Map Texts GetData}
                        ByteString.append
                        {ByteString.make nil}}
   in
      string(name:string AppendedTexts)|NonTexts
   end


   %% Example
   Data =
    "<Students>"
   #"<student Name=\"Dave\" Gender=\"M\"  DateOfBirth=\"1992-07-08\">"
   #"<pet type=\"dog\" Name=\"Rover\" />"
   #"</student>"
   #"</Students>"

   [StudentsDoc] = {Parser parseVS(Data $)}
   Students = {Deserialize StudentsDoc}
in
   {Show Students.student.pet.type}


On Tue, Jul 6, 2010 at 5:17 PM, mark richardson<[email protected]>  wrote:
Hi,

Before I get lots of replies about the Oz-stdlib and the expat module, I was 
wondering if anyone knows of a much simpler XML parser or how I can use the 
existing ones to get what I need.
Although I need XML for my system (for programs in other languages), I can 
govern exactly what is produced by them and what they expect to see in return, 
so I don't need full XML compatability. What I was hoping for was an XML parser 
that would just give me a record with tags as sub-records and elements as 
feature/field pairs so that I can do things like:

X=Xml.tag1.tag2.element1

(in some ways very similar to the BeautifulSoup package for Python).
I did begin trying to write my own specialised parser but the recursion 
necessary gave me a serious headache :+)
I guess it might be possible to create such a parser class derived from the 
existing ones but frankly I'm not expert enough to be able to do that.

I'd be very grateful if anyone can offer any help with this.

Regards

Mark Richardson
_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users
_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users


--
Mark Richardson MBCS
Email: [email protected]

_________________________________________________________________________________
mozart-users mailing list                               
[email protected]
http://www.mozart-oz.org/mailman/listinfo/mozart-users

Reply via email to