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