How to loop n times, one level per loop in an xml file - c++

This is something that I feel should be easy, but after many hours I still can't figure it out. I tried googling it but it would seem the only way my brain wants to ask the question is in 3 lines of explanation, which doesn't really work with google. Feel free to edit if you have a better way to phrase it.
I have an xml file, say this:
<tag1>
<tag2>
<tag3>
...
</tag3>
</tag2>
</tag1>
The document may have many tag1, tag2 and tag3 per parent.
Using pugixml for c++, I want to perform an action on the selected node. Here's pseudo-code of what I'd like to accomplish, but in a way that I know is wrong and not really doable.
for(pugi::xml_node tag1 : doc->child("tag1").children()){
//Do something with tag1
for(pugi::xml_node tag2 : doc->child("tag1").child("tag2").children()){
//Do something with tag2
for(pugi::xml_node tag3 : doc->child("tag1").child("tag2").child("tag3").children()){
//Do something with tag3
}
}
}
Just looking at this, it's pretty simple to find what won't work... I need to be able to interact with the doc.child().child().child().child()..... inside the loop. Having to add the .child() for each iteration prevents me from doing something of the recursive style, such as:
void loopXNestedTimes(int n){
if(n==0) return;
// Do my stuff
loopXNestedTimes(n-1);
}
Any clue how I'd go about it? I'm using Qt and c++, but am still learning both, so there might be language features I'm missing that allow this.

Use tag1 to get tag2 elements (and not doc) and use tag2 to get tag3 elements, which I think is the crucial point that you're missing.
Your code snippet should look like this:
for (pugi::xml_node tag1 : doc->child("tag1").children()){
//Do something with tag1
for (pugi::xml_node tag2 : tag1.child("tag2").children()){
//Do something with tag2
for (pugi::xml_node tag3 : tag2.child("tag3").children()){
//Do something with tag3
}
}
}

Related

Joining 2 Hashes/Map/Table into 1 with defined key condition in Freemarker

Good Day All,
I face some situation which i have base data like this as hashes/maps/tables
And my goal is text output like this
i've tried to have code such a
<#list Detail as d>
<#list Header as h><#if H.Hno == d.DocNo>${h.Hno};${h.Htype};</#if></#list>${d.Seq};${d.Name};<#list Header as h><#if H.Hno == d.DocNo>${h.Hcode}</#if></#list>${d.Status}
</#list>
but it said somewhat Hno evaluate null or missing.
Is there any way to solve and efficient way this ?
Appreciate you guys support

Groovy Collect List of Lists

I have a list of lists similar to this:
[[NAME:JFK, ENUMBER:E12365576], [NAME:Connor Moore, ENUMBER:E12365575]]
I know that if i do:
data.collect {s -> s.eNumber}
I get:
["E12365576", "E12365575"]
What I want to end up with though is something like:
["E12365576 JFK", "E12365575 Connor Moore"]
//Or, If possible something like below
["E12365576 (JFK)", "E12365575 (Connor Moore)"]
I've been looking and haven't found something similar to help me figure it out. Any help is appreciated, thanks
data.collect {s -> "$s.ENUMBER ($s.NAME)" }
or, more precisely
data.collect { "$it.ENUMBER ($it.NAME)" }
by using implicit it

Syntax for list delimiters in template

I'm writing an application that allows the user to configure the output using templates. For example:
Variables:
name = "BoppreH"
language = "Python"
Template:
My name is {name} and I like {language}.
Output:
My name is BoppreH and I like Python.
This works fine for simple data, like strings and numbers, but I can't find a good syntax for lists, more specifically for their delimiters.
fruits = ["banana", "apple", "watermelon"]
I like {???}.
I like banana, apple, watermelon.
In this case the desired delimiter was a comma, but how can the user specify that? Is there some template format with this feature?
I'm more concerned about making the syntax simple to understand, regardless of language or library.
Implement filters, and require their use for non-scalar types.
I like {fruits|join:", "}.
Typically, a list contains an unknown number of members, and sometimes variables/placeholders of its own. An example might be listing the name of a person along with their phone numbers. The desired output might look something like this:
John Doe
555-1212
555-1234
In a templating system that supported this, you'd need two types of variables: One that designated a placeholder for a value (like the curly braces you're using now), and another to denote the start and end of the list. So, something like this:
{name}
{{phone_numbers}}{phone}{{/phone_numbers}}
Your array of values might look like this:
values = [names: "John Doe", phone_numbers: [ phone: "555-1212", phone: "555-1234"]]
Each value in the "phone_numbers" array would create a new instance of everything that existed between {{phone_numbers}} and {{/phone_numbers}}, placing the values contained within those two "tags".

pig - parsing string with regex

I'm stuck on string parsing in Pig.
I have looked at the documentation around regex_extract and regex_extract_all and hoped to use one of those functions.
I have file '/logs/test.log':
cat '/logs/test.log'
user=242562&friend=6226&friend=93856&age=35&friend=35900
I want to extract the friend tags from the url, and in this case, I have 3 identical tags. regex_extract seems to only work for the first instance, which is what I expected, and for regex_extract_all, it seems like I have know the whole string pattern, which changes on each row of the source file.
It looked ok with regex_extract, but this option only gives me the first one.
[root#test]# pig -x local
A = LOAD './test.log';
B = FOREACH A GENERATE REGEX_EXTRACT($0, 'friend=([0-9]*)',1);
dump B;
(6226)
The examples I see for regex_extract_all show regex where you seek out all the tags:
B = FOREACH A GENERATE FLATTEN(REGEX_EXTRACT_ALL($0, 'user=([0-9]+?)&friend=([0-9]+?)&friend=([0-9]+?)&.+?'));
dump B;
(242562,6226,93856)
That seems to work, but I really just want to extract the friends - (6226,93856,35900). I also have cases where there might be more-than or less-than 3 friends per user.
Any ideas?
Also looking at using something like FLATTEN(TOKENIZE($0,'&')) and then somehow only filtering on the SUBSTRING($0,0,INDEXOF($0,'=')) == 'friend' or something like that, but wanted to see if anyone knew a good regex approach.
This can be achieved by simple string manipulations:
inputs = LOAD 'input' AS (line: chararray);
tokenized = FOREACH inputs GENERATE FLATTEN(TOKENIZE(line, '&')) AS parameter;
filtered = FILTER tokenized BY INDEXOF(parameter, 'friend=') != -1;
result = FOREACH filtered GENERATE SUBSTRING(parameter, 7, (int)SIZE(parameter)) AS friend_number;
DESCRIBE tokenized;
DUMP tokenized;
DESCRIBE filtered;
DUMP filtered;
DESCRIBE result;
DUMP result;
result:
tokenized: {parameter: chararray}
(user=242562)
(friend=6226)
(friend=93856)
(age=35)
(friend=35900)
filtered: {parameter: chararray}
(friend=6226)
(friend=93856)
(friend=35900)
result: {friend_number: chararray}
(6226)
(93856)
(35900)
Try this:
a = LOAD '/logs/test.log' USING PigStorage('&') as (f1, f2, f3, f4, f5);
b = FOREACH a GENERATE REGEX_EXTRACT(f2,'friend=([0-9]*)', 1),
REGEX_EXTRACT(f3,'friend=([0-9]*)', 1),
REGEX_EXTRACT(f5,'friend=([0-9]*)', 1);
DUMP b;

Get people from Highrise by Highrise API, which have tags: tag1 OR tag2

I mean I need info of people from Highrise with tags: tag1 OR tag2
"OR" is very important.
For example:
GET people.xml?tag_id=2123123 //how i get people w tag1
GET people.xml?tag_id=5656622 //how i get people w tag2
but there are people, who have both tags and I don't what to duplicate them after merge to xml file.