Nesting of xsl:key() within xsl:key() & combining results of xsl:key() - xslt

I have 2 unrelated questions. I need to do a grouping of data using XSLT. I need this to function like how a nested IF within an IF would function. After which, I need to group the data so that I can split it into multiple files according to the Group condition.
Using XSLT Version 1.0 :
Q1) How do you nest a key() within another key() (i.e. Use the result nodes returned from the first key() as current node-list to search for 2nd key() condition to group my data)?
Q2) Can I combine the results of 2 key() functions? Say, I want to execute code for all nodes with Key values of "A" and "B".
Does anyone know how to solve Q1 and Q2?
Appreciate your help very much! I hope the questions are clear enough. Let me know if you need examples of input and output.
Regards,
Melita.

On Q2, did you mean "values of 'A' OR 'B'"? The key for an element has only one value.
<xsl:for-each select="key('myKey', 'A') | key('myKey', 'B')">
...
</xsl:for-each>

Related

Is there any way to remove Duplicate Values From a Variable in XSLT

I have a Variable
Numbers=900354655,900354655,900354656
But I Want,
Numbers=900354655,900354656
Could you please help in this situation. Thanks in Advance
It is not clear what you mean by "values" in a variable. If you have a variable that contains a delimited string e.g. "900354655,900354655,900354656" then in XSLT 2.0 you can use the expression:
distinct-values(tokenize($yourVariable, ','))
to construct a sequence of distinct values (900354655, 900354656)

How to get the first occurrence of value with the matching number from multiple sets

I have request comes with multiple elements where I need the first occurrence of the where data_type="3". Hence there could be multiple values comes as 0,2,3,4 in random.
When I tried to put the below Xpath function it's returning the all values where data_type='3'
<xsl:value-of select="/process/TransactionType/data_xml/transaction/sub_documents/transactionLine[#data_type='3']/Ref"/>
Full input and output code click here code snippet
How I can get the one value instead all values.
Please help me out here.
Well, with XPath if exp gives you a sequence of values and you want the first use e.g. (exp)[1] i.e. (/process/TransactionType/data_xml/transaction/sub_documents/transactionLine[#data_type='3']/Ref)[1].

Extract 2 non-consecutive strings and always sort them in desired way

I'm finishing my regex project in google sheets and this last question I have for it. Hope you can help.
I have a column, in which one cell may or may not contain multiple strings.
This is an example of it (start position):
Now I want to extract the following values:
Team (A)
Team B
Team (A) Team B
Desired end result image:
I want to check for all 3 possible values, and always sort them with Team (A) as a priority. In case the initial cell (C column) is empty, the result is empty.
I tried this formula:
=ARRAYFORMULA(IFERROR(REGEXEXTRACT(C2,"Team \(A\)|Team B|[Team \(A\) "&" Team B]"),IF(C2="","")))
Problems I have:
Don't know how to give priority :/
Don't know how to give them sorting order :/
All help welcome, thank you.
=ARRAYFORMULA(REGEXREPLACE(IFERROR(
REGEXEXTRACT(C2:C, "(Team \(A\))")&CHAR(10))&
IFERROR(REGEXEXTRACT(C2:C, "(Team B)")), "\n$", ))

Need to extract the sibling child value using regex

In the below XML snippet,i need to extract and store in a variable the value of NAME1, when the Parent node is E1 and the element PARVW equals AG.
For the above snippet, the answer shud be: soldtoid =W
Thanks in advance for the help.
Use an existing XML parser (such as XML::LibXML) rather than writing your own shitty one!
You can access the desired node using the following XPath:
//E1EDKA2[PARVW/text()="AG"]/NAME1
I think that can be simplified to
//E1EDKA2[PARVW="AG"]/NAME1

Element-in-List testing

For a stylesheet I'm writing (actually for a set of them, each generating a different output format), I have the need to evaluate whether a certain value is present in a list of values. In this case, the value being tested is taken from an element's attribute. The list it is to be tested against comes from the invocation of the stylesheet, and is taken as a top-level <xsl:param> (to be provided on the command-line when I call xsltproc or a Saxon equivalent invocation). For example, the input value may be:
v0_01,v0_10,v0_99
while the attribute values will each look very much like one such value. (Whether a comma is used to separate values, or a space, is not important-- I chose a comma for now because I plan on passing the value via command-line switch to xsltproc, and using a space would require quoting the argument, and I'm lazy-enough to not want to type the extra two characters.)
What I am looking for is something akin to Perl's grep, wherein I can see if the value I currently have is contained in the list. It can be done with sub-string tests, but this would have to be clever so as not to get a false-positive (v0_01 should not match a string that contains v0_011). It seems that the only non-scalar data-type that XSL/XSLT supports is a node-set. I suppose it's possible to convert the list into a set of text nodes, but that seems like over-kill, even compared to making a sub-string test with extra boundaries-checking to prevent false matches.
Actually, using XPath string functions is the right way to do it. All you have to make sure is that you test for the delimiters as well:
contains(concat(',' $list, ','), concat(',', $value, ','))
would return a Boolean value. Or you might use one of these:
substring-before(concat('|,' $list, ',|'), concat(',', $value, ','))
or
substring-after(concat('|,' $list, ',|'), concat(',', $value, ','))
If you get an empty string as the result, $value is not in the list.
EDIT:
#Dimitre's comment is correct: substring-before() (or substring-after()) would also return the empty string if the found string is the first (or the last) in the list. To avoid that, I added something at the start and the end of the list. Still contains() is the recommended way of doing this.
In addition to the XPath 1.0 solution provided by Tomalak,
Using XPath 2.0 one can tokenize the list of values:
exists(tokenize($list, ',')[. = $value])
evaluates to true() if and only if $value is contained in the list of values $list