Re: RuleDelayed for parsing XML with multiple children
- To: mathgroup at smc.vnet.net
- Subject: [mg109626] Re: RuleDelayed for parsing XML with multiple children
- From: Albert Retey <awnl at gmx-topmail.de>
- Date: Sat, 8 May 2010 07:09:05 -0400 (EDT)
- References: <hs0plr$doj$1@smc.vnet.net>
Am 07.05.2010 12:22, schrieb Zach Bjornson: > Hi, > > I'm trying to extract multiple values (same depth, different physical > level) from an XML tree using RuleDelayed, but I realized that using > RuleDelayed only extracts one of the children. That is: > > XmlTree follows the form: > <LevelA> > <LevelB> > <Child>value1</Child> > </LevelB> > <LevelB> > <Child>value2</Child> > </LevelB> > </LevelA> > > I want those two values. > > Cases[XmlTree, > XMLElement["LevelA",_,{___,XMLElement["LevelB",_,{___,XMLElement["Child",_,{WantThisValue_}],___}],___}]:>{WantThisValue},Infinity] > > This only gives value1. I can explicitly add more XMLElement tags to get > the other value > > Cases[XmlTree, > XMLElement["LevelA",_,{___,XMLElement["LevelB",_,{___,XMLElement["Child",_,{WantThisValue_}],___}],___,XMLElement["LevelB",_,{___,XMLElement["Child",_,{WantThisValueToo_}],___}]:>{WantThisValue,WantThisValueToo},Infinity] > > but I don't want to use an explicit structure because the number of > children/values varies. > > Any have suggestions for the best alternative method to the RuleDelayed > syntax I'm using? Changing the innermost XMLElement tag to simply > XMLElement["Child",_,_] gives the proper answer, albeit with the messy > flanking tree structure. Dropping indices is not an ideal solution. What's wrong with: Cases[XmlTree, XMLElement["Child", _, {val_}] :> val, Infinity] which will find all "Child" elements. It will have the drawback that it will find "Child" elements also when the appear not in the exact structure you have submitted. To achieve that, you could do something like this: Cases[ Cases[ Cases[XmlTree, XMLElement["LevelA", _, levelA_] :> levelA, Infinity], XMLElement["LevelB", _, levelB_] :> levelB, Infinity ], XMLElement["Child", {}, {val_}] :> val, Infinity ] which will find all LevelA-Subtrees, then all LevelB-Subtrees of those and finally all Child elements within the LevelB-Subtrees. Thus it will avoid to find Child which are not in the correct hierarchy. Maybe you want to also restrict the Level-Definition in the Cases to only find elemnts at the right level... hth, albert