Template nested grouping with Sort option - sorting

I would like to generate a report using RTF Template which looks like the below:
Expected Output:
US
Cover Insured
123456 INS1, INSB, INSA
987654 INS2
or
US
Cover Insured
123456 INS1
INSB
INSA
987654 INS2
Here "Insured" data is present both in Parent and child hierarchy with different tag names. Parent "InsuredAccnt" (INS1 in my XML) should be displayed first followed by child "InsuredAccounts" which will be sorted by "Share" - Descending.
XML:
<?xml version="1.0" encoding="UTF-8" ?>
<InsuredReport>
<GroupPolicies>
<Cover>123456</Cover>
<Customer>Customer</Customer>
<InsuredAccnt>INS1</InsuredAccnt>
<Organization>US</Organization>
<ListOfGroupPolicies_InsuredAccount>
<GroupPolicies_InsuredAccount>
<InsuredAccount>INSA</InsuredAccount>
<Share>5</Share>
</GroupPolicies_InsuredAccount>
<GroupPolicies_InsuredAccount>
<InsuredAccount>INSB</InsuredAccount>
<Share>20</Share>
</GroupPolicies_InsuredAccount>
</ListOfGroupPolicies_InsuredAccount>
</GroupPolicies>
<GroupPolicies>
<Cover>987654</Cover>
<Customer>ABC</Customer>
<InsuredAccnt>INS2</InsuredAccnt>
<Organization>US</Organization>
<ListOfGroupPolicies_InsuredAccount />
</GroupPolicies>
</InsuredReport>
I am not sure how to upload the RTF used, but this is a gist of the same:
RTF:
<?for-each-group:GroupPolicies;./Organization?>
Grouping within Table based on Cover
<?for-each-group:current-group();./Cover?>
Displaying "Insured"
<?InsuredAccnt?>
<?for-each-group:current-group();./GroupPolicies_InsuredAccount?><?sort: Share?><?InsuredAccount?><?end for-each-group?>
When I give this, my system runs forever and I am forced to kill the session.
Please could someone point out where I am wrong.

I was able to achieve the desired using the following:
<?InsuredAccnt?>
<?for-each:GroupPolicies_InsuredAccount?><?sort:Share;'descending';data-type='number'?><?InsuredAccount?><?end for-each?>
The Current-Group() tag was not needed a second time. This produces Output # 2, i.e displaying the "InsuredAccounts" one after the other.

Related

Wildcard XPath nested element selection by example

I am being given XML that looks like this:
<?xml version='1.0' encoding='UTF-8'?>
<singleton-list>
<fizzbuzz>
<amountId>123</amountId>
<countryId>456</countryId>
<action>Overwrite</action>
</fizzbuzz>
</singleton-list>
However, the outer-most element (in this case, singleton-list) will be different each time, and will be one of many different values. For instance I might get another XML message that looks like this:
<?xml version='1.0' encoding='UTF-8'?>
<aggregateList>
<fizzbuzz>
<amountId>123</amountId>
<countryId>456</countryId>
<action>Overwrite</action>
</fizzbuzz>
</aggregateList>
I'm trying to write an XPath that selects the fizzbuzz out of each message I receive, regardless of what the outer-most element is (singleton-list, aggregateList, or otherwise).
I think I could do something involving a wildcard, but I'm not sure if asterisks have special meaning in XPath or if I'm going about this the wrong way.
My best attempt at an XPath to do this selection is:
/*/fizzbuzz
Is this correct or is there a better way to do this?
either you can use //fizzbuzz or /*/fizzbuzz.

XPATH Select All Attributes attr Except One On Specific Element elem

I was selecting all attributes id and everything was going nicely then one day requirements changed and now I have to select all except one!
Given the following example:
<root>
<structs id="123">
<struct>
<comp>
<data id="asd"/>
</comp>
</struct>
</structs>
</root>
I want to select all attributes id except the one at /root/structs/struct/comp/data
Please note that the Xml could be different.
Meaning, what I really want is: given any Xml tree, I want to select all attributes id except the one on element /root/structs/struct/comp/data
I tried the following:
//#id[not(ancestor::struct)] It kinda worked but I want to provide a full xpath to the ancestor axis which I couldn't
//#id[not(contains(name(), 'data'))] It didn't work because name selector returns the name of the underlying node which is the attribute not its parent element
The following should achieve what you're describing:
//#id[not(parent::data/parent::comp/parent::struct/parent::structs/parent::root)]
As you can see, it simply checks from bottom to top whether the id attribute's parent matches the path root/structs/struct/comp/data.
I think this should be sufficient for your needs, but it does not 100% ensure that the parent is at the path /root/structs/struct/comp/data because it could be, for example, at the path /someOtherHigherRoot/root/structs/struct/comp/data. I'm guessing that's not a possible scenario in your XML structure, but if you had to check for that, you could do this:
//#id[not(parent::data/parent::comp/parent::struct/parent::structs/parent::root[not(parent::*)])]

Summing XML Data in MSWord Mail Merge

I have a report card written in Word that uses an XML file for its input. In the XML file, if a student remains in the same section all three trimesters there will be one node for that class; if they change sections at the trimester they'll have one node for each section. The nodes look something like this (greatly simplified):
<ReportCardSectionFB Abs1="2" Abs2="11" CourseID="ELMATH1" CourseTitle="Math" PeriodStart="3" TeacherName="Jones, Jennifer" TermCode="Year" SectionID="ELMATH1-4" />
<ReportCardSectionFB Abs1="1.50" Abs2="6" CourseID="ELMATH1" CourseTitle="Math" PeriodStart="3" TeacherName="Smith, Tina" TermCode="Year" SectionID="ELMATH1-3" />
There is no indicator within the XML as to which trimester the node belongs to.
In the Word document, we're pulling the absence data with the following mail merge command:
{MERGEFIELD "ReportCardSectionFB[#PeriodStart='3']/ #Abs1" \# 0.# \* MERGEFORMAT }
That's not working in this situation: it only gets the absence data from the first node it comes across, i.e.: 2.0. Is there a way to get the sum of #Abs1 for all period 3 classes, i.e.: 3.5? If not, is there a way to only get the last #Abs1 for period 3, i.e.: 1.5?
I recommend you to use this 3rd party product, which can use xml as input and is capable of merging it with MS Word template. I is also much more powerful than the built-in Word's mail merge. You can see some examples here.
You could also try summing the absences in Synergy - there's a new checkbox under AttDef1, 2, etc. that adds up all the absences for the data range - Include all day data for the entire date range regardless of section enrollment or section timeframe. That way the absences should be the same for each section, if that works for your district.
You can also try the SET function in Word to nest the MERGEFIELDS as bookmarks and use the Word operator functions to then add the bookmarks.

UCM - How to access repeat children nodes from XML

I've got an XML document -
<PARTNER>
<CompanyName>ABCD<CompanyName>
<Address>XYZ</Address>
<OFFER>
<OFFERNAME>ABCDEFG</OFFERNAME>
<OFFERDESC>XYZWV</OFFERDESC>
</OFFER>
<OFFER>
<OFFERNAME>123456</OFFERNAME>
<OFFERDESC>98765</OFFERDESC>
</OFFER>
</PARTNER>
I want to access the individual OFFERNAME, OFFERDESC elements from each of the OFFER
tags.
<!--$ssIncludeXml("dDocName","wcm:root/wcm:element[#name="OFFER"]/node()")-->
Gives me the entire ABCDEFG XYZWV 123456 98765 which I do not want. Is there a
way I can access OFFERNAME, OFFERDESC from each of the OFFER tags?
PS: I have 2 OFFER nodes and each of them has 17 children nodes. When I try
<!--$ssGetXmlNodeCount("dDocName", "wcm:root/wcm:element[#name='OFFER']/node()")-->, I
get 34.
<!--$ssIncludeXml("dDocName","wcm:root/wcm:element[#name="OFFER"][1]/node()")--> prints
nothing.

XPath query for node names matching a certain pattern

Is there a way to apply XPath's starts-with function to a node's name instead of its value? I want to select the FOObar and FOObaz nodes from the following XML document without selecting the notFOO node:
<?xml version="1.0" encoding="UTF-8" ?>
<RootNode>
<FOObar xmlns="http://sample.example.com">
<value>numOne</value>
</FOObar>
<FOObaz xmlns="http://sample.example.com">
<value>numTwo</value>
</FOObaz>
<notFOO xmlns="http://sample.example.com">
<value>numThree</value>
</notFOO>
</RootNode>
I get that it's possible to use starts-with to search based on text nodes, e.g.
//sample:value[starts-with(.,'num')]
Is there a way to write the following that is syntactically valid?
//sample:[starts-with(node(),'FOO')]
This question originally came with an SSCCE, but now that the question is answered, all that code is just clutter. It's still available in the revision history, of course.
Use the name() or local-name() functions to refer to nodes by name:
//*[starts-with(local-name(), 'FOO')]

Resources