Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

XPath and recursion

Moderators: larsivi kris

Posted: 09/21/08 14:48:21

Hi, I've been fighting wich tango XmlPath? for a while and got no success, so I'm posting here for some clarification. My code just needs to iterate over a xml and build some objects, recursively because I need group/subgroup stuff.

Here is my code:

void parseFields(Node actual, FieldMap map)
{
	string id;
	uint iid;
		
	foreach (Node n; actual.query["field"].nodes)
	{
		id = n.getAttribute("id").value;
		iid = Integer.toInt!(char)(id);
		FieldBase field = new FieldBase(iid, n.value);
				
		Stdout.formatln("Added field {} = {}", id, n.value);
		map.addField(field);
	}		
}
		
void parseMessage(Node actual, FieldMap map)
{
	string id;
	uint iid;
	
	//parsing outer scope fields
	parseFields(actual, map);
			
	//Stdout.formatln("{}" , actual.query["groups"]);
	foreach(Node groups; actual.query["groups"].nodes)
	{							
		iid =  Integer.toInt!(char)(groups.getAttribute("id").value);
			
		foreach(Node nodeGroup; groups.query["group"].nodes)
		{								
			Group group = new Group(iid);					
			parseMessage( nodeGroup , group);				
			map.addGroup(group);
		}
	}
}

It's pretty simple (I think). But the problem is: when there are more than 1 group under groups block, It's not being processessed. I have fields on it but on parseFields the foreach just goes out like none was found. Using manual XPath I can see that the fields are there.

I've tried using dup like the documentation, but that showed no difference.

XML sample:

<?xml version="1.0" encoding="UTF-8"?>
<message>
        <groups id="15" count="2">
                <group>
                        <field id="12">Bogota</field>
                        <field id="13">1</field>
                        <groups id="14" count="1">
                                <group>
                                        <field id="20">1</field>
                                </group>
                        </groups>
                </group>
                <group>
                        <field id="12">Brasil</field>
                        <field id="13">2</field>
                        <groups id="14" count="1">
                                <group>
                                        <field id="20">1</field>
                                </group>
                        </groups>
                </group>
        </groups>
</message>

Output, after converting back to xml from my object:

<?xml version="1.0" encoding="UTF-8"?>
<message>
        <groups id="15" count="2">
                <group>
                        <field id="12">Bogota</field>
                        <field id="13">1</field>
                        <groups id="14" count="1">
                                <group>
                                        <field id="20">1</field>
                                </group>
                        </groups>
                </group>
                <group>
                </group>
        </groups>
</message>
Author Message

Posted: 09/21/08 16:59:31

	foreach(Node groups; actual.query["groups"].nodes.dup)

You're missing a .dup, as illustrated above. The subsequent inner query on groups will otherwise reset the outer foreach to do the wrong thing.

Posted: 09/21/08 17:22:31

kris wrote:
	foreach(Node groups; actual.query["groups"].nodes.dup)

You're missing a .dup, as illustrated above. The subsequent inner query on groups will otherwise reset the outer foreach to do the wrong thing.

LOL, I've tried many approaches using dup, and none worked. Maybe I was too lazy yesterday. Thanks, it worked like a charm!