I have a large xsl:choose (i.e. ~100) where the xsl:when is testing using a regex. I'm looking for a cleaner way, can this be replaced with a lookup table? This is just a sample of my code looks like today
<xsl:when test="matches($seq4, '^\w+-\w+-\w+-\d+/NCell:.+$', 'i')">
<xsl:value-of select="'NEIGHBOR'"/>
</xsl:when>
<xsl:when test="matches($seq4, '(/ULoCell:NodeB Function Name=.*, Local Cell ID=.*)', 'i')">
<xsl:value-of select="'SECTOR'"/>
</xsl:when>
I appreciate the help and I think I can make the Map sample code work if I make it a separate XML file and use import or include. I'm just wonder how difficult it would be to convert this into a document lookup. I'm familiar with document lookup and keys, but I have no idea how I would code the lookup using a regex? I Have the following lookup document:
<Telsa xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Row Key1="^[A-Z0-9]+/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=[0-9]+, Cell Name=.*/CnOperator:CnOperatorId=[0-9]+$" ElementType="CELL_CORE_OPERATOR" RegexReplace="'^([A-Z0-9]+)/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=([0-9]+), Cell Name=.*/CnOperator:(CnOperatorId=[0-9]+)', '$1/CELL:$2/$3'"></Row>
<Row Key1="^\w+-\w+-\w+-\d+/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=[0-9]+, Cell Name=.*, eNodeB ID=[0-9]+, Cell.*$" ElementType="CELL" RegexReplace="'^\w+-\w+-\w+-\d+/Cell:eNodeB Function Name=([A-Z0-9]+), Local Cell ID=([0-9]+), Cell Name=.*, eNodeB ID=([0-9]+), Cell.*$', '$1/Cell:$2'"></Row>
<Row Key1="^\w+-\w+-\w+-\d+/EthernetInterface:Ethernet Interface No.=.*$" ElementType="EthernetInterface" RegexReplace="'^(\w+-\w+-\w+-\d+)/EthernetInterface:Ethernet Interface No.=([0-9]+)$' , '$1/No=$2'"></Row>
<Row Key1="^[A-Z0-9]+/CELL:Local cell identity=[0-9]+, Cell Name=.*/OPERATOR:CnOperatorId=[0-9]+$" ElementType="CELL_CORE_OPERATOR" RegexReplace="'^([A-Z0-9]+/CELL:)Local cell identity=([0-9]+), Cell Name=.*/OPERATOR:(CnOperatorId=[0-9]+)' , '$1$2/$3'"></Row>
<Row Key1="^[A-Z0-9]+/Cell:Local cell identity=[0-9]+, Cell Name=.*, eNodeB identity=[0-9]+$" ElementType="CELL" RegexReplace="'^([A-Z0-9]+/Cell:)Local cell identity=([0-9]+), Cell Name=.*, eNodeB identity=[0-9]+$', '$1$2'"></Row>
<Row Key1="^[A-Z0-9]+/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=[0-9]+, Cell Name=.*, eNodeB ID=[0-9]+$" ElementType="CELL" RegexReplace="'^([A-Z0-9]+)/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=([0-9]+), Cell Name=.*, eNodeB ID=([0-9]+)$', '$1/Cell:$2'"></Row>
<Row Key1="^[A-Z0-9]+/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=[0-9]+, Cell Name=.*, eNodeB ID=[0-9]+$" ElementType="CELL" RegexReplace="'^([A-Z0-9]+)/Cell:eNodeB Function Name=[A-Z0-9]+, Local Cell ID=([0-9]+), Cell Name=.*, eNodeB ID=([0-9]+)$', '$1/Cell:$2'"></Row>
</Telsa>
I would define the lookup with
<xsl:key name="table-lookup" match="Row" use="#Key1"/>
<xsl:variable name="LookupDoc" select="document('Telsa.xml')/Telsa"/>
How do I code the key lookup though?
<xsl:value-of select="key('table-lookup', $curr_key, $LookupDoc)/#ElementType"/>
Perhaps the following is what you are looking for, it stores the regular expressions, flags, and result in an XML structure and then looks up the first matching element:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:param name="pattern-map" as="element(map)*">
<map pattern="^\w+-\w+-\w+-\d+/NCell:.+$" flags="i">NEIGHBOR</map>
<map pattern="(/ULoCell:NodeB Function Name=.*, Local Cell ID=.*)" flags="i">SECTOR</map>
</xsl:param>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<xsl:copy>
<xsl:value-of select="$pattern-map[matches(current(), #pattern, #flags)][1]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When run against
<root>
<item>a-b-c-1/NCell:x</item>
<item>/ULoCell:NodeB Function Name=x, Local Cell ID=.y</item>
</root>
the output is
<root>
<item>NEIGHBOR</item>
<item>SECTOR</item>
</root>
Be careful if your regular expressions contain curly braces { or } as with a literal result element like <map pattern="\w{2}" flags="i">foo</map> this would be interpreted as an attribute value template so you would need to double them as in <map pattern="\w{{2}}" flags="i">foo</map>.
I like this solution, the only other question is can this logic be placed into an external document much like the lookup table?
Related
How can I detect that a string ends with a value from a pre-determined array?
Couldn't figure it out myself from other questions on SO because they ask about a complete string match.
Something like this
<xsl:template match="card">
<xsl:variable name="word" select="k" />
<xsl:variable name="obviouslyRussianSuffixes" select="('изм', 'ия', 'ист', 'ёр', 'ца', 'фон')" />
<xsl:if test="ends-with($word, $obviouslyRussianSuffixes)">
<xsl:value-of select="$word" />
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:template>
I think you want the test to be some $suffix in $obviouslyRussianSuffixes satisfies ends-with($word, $suffix).
I want to compare a single value if it's existing to an array. I have an XML input file:
<wd:Report_Entry
xmlns:wd="urn:com.workday.report/CRI_-_INTSG031_CM_011_-_PUBBS_HSA_Customer_Invoice">
<wd:CFI_ARI_PUBBS_HSA_group>
<wd:pubbsType>1</wd:pubbsType>
<wd:pubbsService>A+</wd:pubbsService>
<wd:validFrom>2019-08-01</wd:validFrom>
<wd:validTo>2100-01-01</wd:validTo>
<wd:CF_FD_PUBBS_HSA_Valid_From_Date>2019-08-01</wd:CF_FD_PUBBS_HSA_Valid_From_Date>
<wd:CF_FD_PUBBS_HSA_Valid_To_Date>2100-01-01</wd:CF_FD_PUBBS_HSA_Valid_To_Date>
</wd:CFI_ARI_PUBBS_HSA_group>
<wd:CFI_ARI_PUBBS_HSA_group>
<wd:pubbsType>1</wd:pubbsType>
<wd:pubbsService>A-</wd:pubbsService>
<wd:validFrom>2019-08-01</wd:validFrom>
<wd:validTo>2100-01-01</wd:validTo>
<wd:CF_FD_PUBBS_HSA_Valid_From_Date>2019-08-01</wd:CF_FD_PUBBS_HSA_Valid_From_Date>
<wd:CF_FD_PUBBS_HSA_Valid_To_Date>2100-01-01</wd:CF_FD_PUBBS_HSA_Valid_To_Date>
</wd:CFI_ARI_PUBBS_HSA_group>
<wd:CFI_ARI_PUBBS_HSA_group>
<wd:pubbsType>FMDAUTOPSY</wd:pubbsType>
<wd:pubbsService>FMDAUTOPSY</wd:pubbsService>
<wd:validFrom>2020-02-02</wd:validFrom>
<wd:validTo>2020-02-01</wd:validTo>
<wd:CF_FD_PUBBS_HSA_Valid_From_Date>2020-02-01</wd:CF_FD_PUBBS_HSA_Valid_From_Date>
<wd:CF_FD_PUBBS_HSA_Valid_To_Date>2100-01-01</wd:CF_FD_PUBBS_HSA_Valid_To_Date>
</wd:CFI_ARI_PUBBS_HSA_group>
<wd:CFI_ARI_PUBBS_HSA_group>
<wd:pubbsType>FMDBODYSTOR</wd:pubbsType>
<wd:pubbsService>FMDBODYSTOR</wd:pubbsService>
<wd:validFrom>2020-01-01</wd:validFrom>
<wd:validTo>2020-01-31</wd:validTo>
<wd:CF_FD_PUBBS_HSA_Valid_From_Date>2020-01-01</wd:CF_FD_PUBBS_HSA_Valid_From_Date>
<wd:CF_FD_PUBBS_HSA_Valid_To_Date>2020-01-31</wd:CF_FD_PUBBS_HSA_Valid_To_Date>
</wd:CFI_ARI_PUBBS_HSA_group>
<wd:Customer_Invoice_Lines_group>
<wd:referenceID>CUSTOMER_INVOICE_LINE-6-46</wd:referenceID>
<wd:Unit_Cost>0</wd:Unit_Cost>
<wd:Quantity>0</wd:Quantity>
<wd:Calculated_Tax_Amount>0</wd:Calculated_Tax_Amount>
<wd:CFI_AC_Merchandise_Amount>100</wd:CFI_AC_Merchandise_Amount>
<wd:Line_Item_Description>LINE ITEM DESC</wd:Line_Item_Description>
<wd:Line_Memo>LINE MEMO</wd:Line_Memo>
<wd:Transaction_Tax_Amount>0</wd:Transaction_Tax_Amount>
<wd:CFI_LRV_Sales_Item_Reference_ID>FMDAUTOPSY</wd:CFI_LRV_Sales_Item_Reference_ID>
</wd:Customer_Invoice_Lines_group>
<wd:CFI_FD_PUBBS_HSA_Current_Date>2020-02-16</wd:CFI_FD_PUBBS_HSA_Current_Date>
</wd:Report_Entry>
I want to know if the wd:CFI_LRV_Sales_Item_Reference_ID value is equal to wd:Customer_Invoice_Lines_group/wd:CFI_ARI_PUBBS_HSA_group/wd:pubbsService and wd:CFI_FD_PUBBS_HSA_Current_Date is greater than wd:CF_FD_PUBBS_HSA_Valid_To_Date and then just return a string value true if there is. I have a code like this but this doesn't work because I'm comparing a value to an object that has multiple values. Not sure how to do compare single value to an array using xslt 2 or 3.. Appreciate the help.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all" version="3.0"
xmlns:wd="urn:com.workday.report/CRI_-_INTSG031_CM_011_-_PUBBS_HSA_Customer_Invoice"
xmlns:d9="urn:this-stylesheet">
<xsl:output method="xml"/>
<xsl:template match="/">
<PUBBS>
<xsl:for-each select="wd:Report_Entry/wd:Customer_Invoice_Lines_group">
<xsl:if test="wd:CFI_LRV_Sales_Item_Reference_ID != ''">
<xsl:for-each select="../wd:CFI_ARI_PUBBS_HSA_group">
<xsl:if test="../wd:CFI_ARI_PUBBS_HSA_group/wd:pubbsService != ''
and wd:CFI_LRV_Sales_Item_Reference_ID = ../wd:CFI_ARI_PUBBS_HSA_group/wd:pubbsService
and xs:date(../wd:CFI_FD_PUBBS_HSA_Current_Date) > xs:date(../wd:CFI_ARI_PUBBS_HSA_group/wd:CF_FD_PUBBS_HSA_Valid_To_Date)
">
<HASINVALIDSALESITEM>
<xsl:value-of select="'true'"/>
</HASINVALIDSALESITEM>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</PUBBS>
</xsl:template>
</xsl:stylesheet>
I have tried to simplify the code by using xpath-default-namespace and by using templates; I have also assumed the two values you want to compare the two details of the various CFI_ARI_PUBBS_HSA_group to only exist once in the input document:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xpath-default-namespace="urn:com.workday.report/CRI_-_INTSG031_CM_011_-_PUBBS_HSA_Customer_Invoice"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-skip"/>
<xsl:template match="/*">
<PUBBS>
<xsl:apply-templates select="CFI_ARI_PUBBS_HSA_group"/>
</PUBBS>
</xsl:template>
<xsl:template match="CFI_ARI_PUBBS_HSA_group[xs:date(//CFI_FD_PUBBS_HSA_Current_Date) > xs:date(CF_FD_PUBBS_HSA_Valid_To_Date)
and
//CFI_LRV_Sales_Item_Reference_ID = pubbsService]">
<HASINVALIDSALESITEM>true</HASINVALIDSALESITEM>
</xsl:template>
</xsl:stylesheet>
At https://xsltfiddle.liberty-development.net/jz1Q1ym that gives an empty <PUBBS/>, which seems the right result as the only CFI_ARI_PUBBS_HSA_group with pubbsService having the value FMDAUTOPSY has a CF_FD_PUBBS_HSA_Valid_To_Date of 2100-01-01 and the CFI_FD_PUBBS_HSA_Current_Date with the value 2020-02-16 is not greater than that.
It is not quite clear whether you want a single output of HASINVALIDSALESITEM even if there are several but the code could obviously adapted.
I can't seem to manage grouping couple based on their MaritalStatus.
I've manage to group all the person that are in a relationship ('DeFacto', 'Married') but can't figuring out how to group them in different households.
Basically if two persons make a couple they will create a Household. The household name will belong to the first person surname in the household, the NumberOfAdults will be hardcoded to '2' and the NumberOfDependants will be summed.
The couple is linked based on the Party.Identifier and the Party.MaritalStatus.RelatedEntityRef
What i have(simplified):
<PartySegment>
<Party Type="Guarantor" PrimaryApplicant="No">
<Identifier>b8b0f908b08e</Identifier>
<Person Sex="Female" FirstHomeBuyer="No" CustomerOfLender="No">
<PersonName>
<NameTitle Value="Lady"/>
<FirstName>Clemansa</FirstName>
<Surname>Sanchez</Surname>
</PersonName>
<MaritalStatus Status="DeFacto">
<RelatedEntityRef>ea384b0bf3f5</RelatedEntityRef>
</MaritalStatus>
<NumberOfDependents>1</NumberOfDependents>
</Person>
</Party>
<Party Type="Applicant" PrimaryApplicant="Yes" ExistingCustomerID="1231">
<Identifier>bd8c65a3ad80</Identifier>
<Person Sex="Female" FirstHomeBuyer="Yes" CustomerOfLender="Yes">
<PersonName>
<NameTitle Value="Mrs"/>
<FirstName>Cheryl</FirstName>
<Surname>Bonkers</Surname>
</PersonName>
<MaritalStatus Status="Married">
<RelatedEntityRef>ee84dc9e38ec</RelatedEntityRef>
</MaritalStatus>
<NumberOfDependents>2</NumberOfDependents>
</Person>
</Party>
<Party Type="Guarantor" PrimaryApplicant="No">
<Identifier>ea384b0bf3f5</Identifier>
<Person Sex="Male" FirstHomeBuyer="No" CustomerOfLender="No">
<PersonName>
<NameTitle Value="Mr"/>
<FirstName>Greg</FirstName>
<OtherName>Morty</OtherName>
<Surname>Sanchez</Surname>
</PersonName>
<MaritalStatus Status="DeFacto">
<RelatedEntityRef>b8b0f908b08e</RelatedEntityRef>
</MaritalStatus>
<NumberOfDependents>0</NumberOfDependents>
</Person>
</Party>
<Party Type="Applicant" PrimaryApplicant="No">
<Identifier>ee84dc9e38ec</Identifier>
<Person Sex="Male" FirstHomeBuyer="No" CustomerOfLender="No">
<PersonName>
<NameTitle Value="Mr"/>
<FirstName>Mark</FirstName>
<Surname>Bonkers</Surname>
</PersonName>
<MaritalStatus Status="Married">
<RelatedEntityRef>bd8c65a3ad80</RelatedEntityRef>
</MaritalStatus>
<NumberOfDependents>0</NumberOfDependents>
</Person>
</Party>
</PartySegment>
The desire output:
<Household UniqueID="b8b0f908b08e-Household"
Name="Sanchez Household"
NumberOfAdults="2"
NumberOfDependants="1"/>
<Household UniqueID="bd8c65a3ad80-Household"
Name="Bonkers Household"
NumberOfAdults="2"
NumberOfDependants="2"/>
What i have so far(simplified): This is working for one couple because is not taking in consideration the MaritalStatus.RelatedEntityRef information
<xsl:template match="PartySegment" mode="Household_Couple">
<xsl:for-each-group select="Party[Person/MaritalStatus/#Status = ('DeFacto', 'Married')]" group-by="Person/MaritalStatus/#Status = ('DeFacto', 'Married')">
<xsl:variable name="owner_id" select="Identifier"/>
<Household UniqueID="{concat(Identifier, '-Household')}"
Name="{normalize-space(concat(Person/PersonName/Surname, ' Household'))}"
NumberOfAdults="{'2'}"
NumberOfDependants="{if(Person/Dependent) then count(current-group()/Person/Dependent) else if(Person/NumberOfDependents) then sum(current-group()/Person/NumberOfDependents) else '0'}">
<xsl:apply-templates select="current-group()/Person/Dependent"/>
</Household>
</xsl:for-each-group>
</xsl:template>
If you can move to XSLT 3.0 then I think a composite grouping key sort((Identifier, key('ref', Person/MaritalStatus/RelatedEntityRef)/Identifier)) of the sort of the two related identifiers can solve this:
<xsl:key name="ref" match="Party" use="Identifier"/>
<xsl:template match="PartySegment">
<xsl:for-each-group select="Party[Person/MaritalStatus/#Status = ('DeFacto', 'Married')]"
composite="yes"
group-by="sort((Identifier, key('ref', Person/MaritalStatus/RelatedEntityRef)/Identifier))">
<Household UniqueID="{concat(Identifier, '-Household')}"
Name="{normalize-space(concat(Person/PersonName/Surname, ' Household'))}"
NumberOfAdults="{'2'}"
NumberOfDependants="{if(Person/Dependent) then count(current-group()/Person/Dependent) else if(Person/NumberOfDependents) then sum(current-group()/Person/NumberOfDependents) else '0'}">
</Household>
</xsl:for-each-group>
</xsl:template>
I get
<Household UniqueID="b8b0f908b08e-Household"
Name="Sanchez Household"
NumberOfAdults="2"
NumberOfDependants="1"/>
<Household UniqueID="bd8c65a3ad80-Household"
Name="Bonkers Household"
NumberOfAdults="2"
NumberOfDependants="2"/>
this way with Saxon 9.8 EE inside of oXygen.
For Saxon 9.8 HE it should be possible to rewrite that as
<xsl:key name="ref" match="Party" use="Identifier"/>
<xsl:template match="PartySegment">
<xsl:for-each-group select="Party[Person/MaritalStatus/#Status = ('DeFacto', 'Married')]"
composite="yes"
group-by="Identifier | key('ref', Person/MaritalStatus/RelatedEntityRef)/Identifier">
<Household UniqueID="{concat(Identifier, '-Household')}"
Name="{normalize-space(concat(Person/PersonName/Surname, ' Household'))}"
NumberOfAdults="{'2'}"
NumberOfDependants="{if(Person/Dependent) then count(current-group()/Person/Dependent) else if(Person/NumberOfDependents) then sum(current-group()/Person/NumberOfDependents) else '0'}">
</Household>
</xsl:for-each-group>
</xsl:template>
For XSLT 2.0 where we don't have composite keys we would need to make sure to construct a single key with both components:
<xsl:template match="PartySegment">
<xsl:for-each-group select="Party[Person/MaritalStatus/#Status = ('DeFacto', 'Married')]"
group-by="string-join((Identifier | key('ref', Person/MaritalStatus/RelatedEntityRef)/Identifier), '|')">
<Household UniqueID="{concat(Identifier, '-Household')}"
Name="{normalize-space(concat(Person/PersonName/Surname, ' Household'))}"
NumberOfAdults="{'2'}"
NumberOfDependants="{if(Person/Dependent) then count(current-group()/Person/Dependent) else if(Person/NumberOfDependents) then sum(current-group()/Person/NumberOfDependents) else '0'}">
</Household>
</xsl:for-each-group>
</xsl:template>
I want to recursively call on element vrijeInhoudGroep, but the node test in the choose clause is not performed. Instead, the second test on element vrijeInhoudElement is successful. Everything I have applied does not work. Can anyone give me a backing?
My xml input:
<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://services" xmlns:v11="http://services11" xmlns:v12="http://services12">
<soapenv:Header/>
<soapenv:Body>
<v1:creeerDocumentRequest>
<v11:documentInhoud>
<v12:vrijeInhoudGroep type="FirstGroep">
<v12:vrijInhoudGroep type="GenesteGroep_1">
<v12:vrijeInhoudElement>
<v12:label>Label1</v12:label>
<v12:waarde>waard1</v12:waarde>
<v12:datatype>tekst1</v12:datatype>
</v12:vrijeInhoudElement>
<v12:vrijeInhoudElement>
<v12:label>Label2</v12:label>
<v12:waarde>waard2</v12:waarde>
<v12:datatype>tekst2</v12:datatype>
</v12:vrijeInhoudElement>
</v12:vrijInhoudGroep>
<v12:vrijInhoudGroep type="GenesteGroep_2">
<v12:vrijeInhoudElement>
<v12:label>Label3</v12:label>
<v12:waarde>waard3</v12:waarde>
<v12:datatype>tekst3</v12:datatype>
</v12:vrijeInhoudElement>
</v12:vrijInhoudGroep>
<v12:vrijeInhoudElement>
<v12:label>Label4</v12:label>
<v12:waarde>waard4</v12:waarde>
<v12:datatype>tekst4</v12:datatype>
</v12:vrijeInhoudElement>
<v12:vrijeInhoudElement>
<v12:label>Label5</v12:label>
<v12:waarde>waard5</v12:waarde>
<v12:datatype>tekst5</v12:datatype>
</v12:vrijeInhoudElement>
</v12:vrijeInhoudGroep>
</v11:documentInhoud>
</v1:creeerDocumentRequest>
</soapenv:Body>
</soapenv:Envelope>
My xml output:
<?xml version="1.0" encoding="UTF-8"?>
<vrijeInhoudGroep type="documentInhoud">
<vrijeInhoudGroep>v12:vrijeInhoudGroep</vrijeInhoudGroep>
<ELLEMENT/>
<mywrapper>
<v12:label xmlns:soapenv="http://s...">Label4</v12:label>
<v12:waarde xmlns:soapenv="http://s..." >waard4</v12:waarde>
<v12:datatype xmlns:soapenv="http://s..." >tekst4</v12:datatype>
</mywrapper>
<mywrapper>
<v12:label xmlns:soapenv="http://s...." >Label5</v12:label>
<v12:waarde xmlns:soapenv="http://s..." >waard5</v12:waarde>
<v12:datatype xmlns:soapenv="http://s...">tekst5</v12:datatype>
</mywrapper>
</vrijeInhoudGroep>
My xslt:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:v11="http://services11" xmlns:v12="http://services12" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:v1="http://services"
version="2.0"
exclude-result-prefixes="v11 v12 v1 xsi xs">
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
<xsl:apply-templates select="//v1:creeerDocumentRequest"/>
</xsl:template>
<xsl:template match="v1:creeerDocumentRequest">
<vrijeInhoudGroep type="documentInhoud">
<xsl:apply-templates select="v11:documentInhoud"/>
</vrijeInhoudGroep>
</xsl:template>
<xsl:template match="v11:documentInhoud">
<xsl:apply-templates select="v12:vrijeInhoudGroep"/>
</xsl:template>
<xsl:template match="v12:vrijeInhoudGroep[#type]">
<vrijeInhoudGroep>
<xsl:value-of select="name()"/>
</vrijeInhoudGroep>
<xsl:choose>
<xsl:when test="v12:vrijeInhoudGroep">
<!-- HERE I TRY A RECURSIVE CALL, BUT THIS TEST DOES'T WORK -->
<xsl:apply-templates select="v12:vrijeInhoudGroep"/>
</xsl:when>
<xsl:when test="v12:vrijeInhoudElement">
<!-- INSTEAD IT COMES HERE TO PROCES THE vrijeInhoudElement -->
<ELLEMENT/>
<xsl:apply-templates select="v12:vrijeInhoudElement"/>
</xsl:when>
<xsl:otherwise><NOPE/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="v12:vrijeInhoudElement">
<mywrapper>
<xsl:copy-of select="node()"/>
</mywrapper>
</xsl:template>
</xsl:stylesheet>
Target xml should be something like this:
<...>
<vrijeInhoudGroep type="EerstGroep">
<vrijeInhoudGroep type="GenesteGroep_1">
<vrijeInhoudElement naam="Label1 format="tekst1">waard1</vrijeInhoudElement>
</vrijeInhoudGroep>
<vrijeInhoudGroep type="GenesteGroep_2">
<vrijeInhoudElement naam="Label2 format="tekst2">waard2</vrijeInhoudElement>
<vrijeInhoudElement naam="Label3 format="tekst3">waard3</vrijeInhoudElement>
</vrijeInhoudGroep>
<vrijeInhoudElement naam="Label3 format="tekst3">waard3</vrijeInhoudElement>
<vrijeInhoudElement naam="Label4 format="tekst4">waard4</vrijeInhoudElement>
</vrijeInhoudGroep>
</...>
What should I do to make this recursive call work properly?
I've the below XML statement
<section level="sect1">
<title><content-style font-style="bold">PRACTICE DIRECTIONS</content-style></title>
</section>
when i try to apply the below condition
<xsl:when test="not(contains(./title/content-style/text(),'PRACTICE DIRECTIONS'))">
<xsl:choose>
<xsl:when test="./section[1]/para/phrase">
<xsl:value-of select="./section[1]/para[1]/phrase"/>
<xsl:for-each select="./section">
<xsl:apply-templates select="." mode="toc"/>
</xsl:for-each>
</xsl:when>
</xsl:choose>
It is working fine
Here I've another condition.
<xsl:when test="not(contains(./title/content-style,'ORDER')) or not(contains(./title/content-style/text(),'PRACTICE DIRECTIONS')) or not(contains(./section[1]/title,'ORDER')) or not(contains(./section[1]/title,'PRACTICE DIRECTIONS'))">
Here this should not let the condition(or the cursor) to get into the inner choose condition as there is not(contains(./title/content-style/text(),'PRACTICE DIRECTIONS')) as one of the conditions.
But here in my case the cursor is moved into the inner choose. Where am I going wrong?
Use AND instead of OR and you'll probably get the result you're after.