Group and split Xmldocument on nth level descendant - xslt

I want to split an XmlDocument into an array of XmlDocuments, where each splitted XmlDocument contains records of a certain period (Year/Month combination). The complicating factor, imo, is that the grouping should occur on nested elements.
Example input:
<?xml version="1.0" encoding="utf-8"?>
<Example>
<RecordA>
<RecordA1>
<RecordA11>
<ElementA11></ElementA11>
</RecordA11>
</RecordA1>
<RecordA2>
<ElementA2></ElementA2>
</RecordA2>
</RecordA>
<RecordB>
<RecordB1>
<ElementB1></ElementB1>
<RecordB11>
<ElementB11></ElementB11>
<RecordB111>
<RecordB1111>
<RecordB11111>
<ElementB11111></ElementB11111>
</RecordB11111>
<ElementB1111></ElementB1111>
<RecordB11112>
<Dates>
<StartDate>2014-05-29</StartDate>
<EndDate>2014-05-29</EndDate>
</Dates>
</RecordB11112>
<RecordB11112>
<Dates>
<StartDate>2014-06-02</StartDate>
<EndDate>2014-06-02</EndDate>
</Dates>
</RecordB11112>
<RecordB11112>
<Dates>
<StartDate>2014-05-21</StartDate>
<EndDate>2014-05-21</EndDate>
</Dates>
</RecordB11112>
<RecordB11112>
<Dates>
<StartDate>2014-04-09</StartDate>
<EndDate>2014-04-09</EndDate>
</Dates>
</RecordB11112>
<RecordB11112>
<Dates>
<StartDate>2014-06-05</StartDate>
<EndDate>2014-06-05</EndDate>
</Dates>
</RecordB11112>
</RecordB1111>
</RecordB111>
</RecordB11>
</RecordB1>
</RecordB>
</Example>
Wanted output:
<?xml version="1.0" encoding="utf-8"?>
<Examples>
<Example>
<RecordA>
<RecordA1>
<RecordA11>
<ElementA11></ElementA11>
</RecordA11>
</RecordA1>
<RecordA2>
<ElementA2></ElementA2>
</RecordA2>
</RecordA>
<RecordB>
<RecordB1>
<ElementB1></ElementB1>
<RecordB11>
<ElementB11></ElementB11>
<RecordB111>
<RecordB1111>
<RecordB11111>
<ElementB11111></ElementB11111>
</RecordB11111>
<ElementB1111></ElementB1111>
<RecordB11112>
<Dates>
<StartDate>2014-05-29</StartDate>
<EndDate>2014-05-29</EndDate>
</Dates>
</RecordB11112>
<RecordB11112>
<Dates>
<StartDate>2014-05-21</StartDate>
<EndDate>2014-05-21</EndDate>
</Dates>
</RecordB11112>
</RecordB1111>
</RecordB111>
</RecordB11>
</RecordB1>
</RecordB>
</Example>
<Example>
<RecordA>
<RecordA1>
<RecordA11>
<ElementA11></ElementA11>
</RecordA11>
</RecordA1>
<RecordA2>
<ElementA2></ElementA2>
</RecordA2>
</RecordA>
<RecordB>
<RecordB1>
<ElementB1></ElementB1>
<RecordB11>
<ElementB11></ElementB11>
<RecordB111>
<RecordB1111>
<RecordB11111>
<ElementB11111></ElementB11111>
</RecordB11111>
<ElementB1111></ElementB1111>
<RecordB11112>
<Dates>
<StartDate>2014-04-09</StartDate>
<EndDate>2014-04-09</EndDate>
</Dates>
</RecordB11112>
</RecordB1111>
</RecordB111>
</RecordB11>
</RecordB1>
</RecordB>
</Example>
<Example>
<RecordA>
<RecordA1>
<RecordA11>
<ElementA11></ElementA11>
</RecordA11>
</RecordA1>
<RecordA2>
<ElementA2></ElementA2>
</RecordA2>
</RecordA>
<RecordB>
<RecordB1>
<ElementB1></ElementB1>
<RecordB11>
<ElementB11></ElementB11>
<RecordB111>
<RecordB1111>
<RecordB11111>
<ElementB11111></ElementB11111>
</RecordB11111>
<ElementB1111></ElementB1111>
<RecordB11112>
<Dates>
<StartDate>2014-06-02</StartDate>
<EndDate>2014-06-02</EndDate>
</Dates>
</RecordB11112>
<RecordB11112>
<Dates>
<StartDate>2014-06-05</StartDate>
<EndDate>2014-06-05</EndDate>
</Dates>
</RecordB11112>
</RecordB1111>
</RecordB111>
</RecordB11>
</RecordB1>
</RecordB>
</Example>
</Examples>

I think you can use Muenchian grouping to identify the first item in each group, then you need to recreate the tree for each group:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="group" match="RecordB11112" use="substring(Dates/StartDate, 1, 7)"/>
<xsl:template match="/">
<Examples>
<xsl:apply-templates select="//RecordB11112[generate-id() = generate-id(key('group', substring(Dates/StartDate, 1, 7))[1])]"/>
</Examples>
</xsl:template>
<xsl:template match="RecordB11112">
<xsl:variable name="to-be-copied" select="key('group', substring(Dates/StartDate, 1, 7))"/>
<xsl:apply-templates select="/*" mode="recreate">
<xsl:with-param name="to-be-copied" select="$to-be-copied"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="#* | node()" mode="recreate">
<xsl:param name="to-be-copied"/>
<xsl:copy>
<xsl:apply-templates select="#*" mode="recreate"/>
<xsl:apply-templates mode="recreate">
<xsl:with-param name="to-be-copied" select="$to-be-copied"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="RecordB11112" mode="recreate">
<xsl:param name="to-be-copied"/>
<xsl:if test="$to-be-copied[generate-id() = generate-id(current())]">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Related

Not select a particular node child Elements in xslt using not

My XML is below. Is it possible to do this in same XSLT?
<response context="XXXX" type="abcd" errorCode="0" >
<output>
<Applicants>
<Applicant>
<IndividualEmployments/>
<Addresses/>
</Applicant>
</Applicants>
<Assets>
<Asset id="12345"></Asset>
</Assets>
<Liabilities>
<Liability id="8765"></Liability>
</Liabilities>
</output>
Desired output should be like below. I want two response nodes, one with Assets and the other with Liabilities.
<response context="XXXX" type="abcd" errorCode="0">
<output>
<Applicants>
<Applicant>
<IndividualEmployments/>
<Addresses/>
</Applicant>
</Applicants>
<Assets>
<Asset id="12345"></Asset>
</Assets>
</output>
<response context="XXXX" type="abcd" errorCode="0">
<output>
<Applicants>
<Applicant>
<IndividualEmployments/>
<Addresses/>
</Applicant>
</Applicants>
<Liabilities>
<Liability id="8765"></Liability>
</Liabilities>
</output>
You need to process the response element and output it twice, making sure the content is different, for instance by passing a parameter:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="response">
<xsl:next-match>
<xsl:with-param name="exclude" tunnel="yes" select="descendant::Liabilities"/>
</xsl:next-match>
<xsl:next-match>
<xsl:with-param name="exclude" tunnel="yes" select="descendant::Assets"/>
</xsl:next-match>
</xsl:template>
<xsl:template match="output">
<xsl:param name="exclude" tunnel="yes"/>
<xsl:copy>
<xsl:apply-templates select="#*, node() except $exclude"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
If needed or wanted you can of course wrap each xsl:next-match I have in an xsl:result-document.

Attempting to remove element and reorder elements in resulting document

I have the following XML and XSLT.
I am attempting to exclude the NotUsed2 element from the resulting document.
I need to reorder the resulting so that AutoTypesetInfo follows NotUsed3.
XML:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<Plan xmlns="http://www.ccieurope.com/xmlns/CCIPlanner">
<Header>
<Update>0</Update>
<NewsPaper>Pub1</NewsPaper>
<Date>080818</Date>
<Zone>MAIN</Zone>
<Edition>1st</Edition>
<Pages>26</Pages>
<Section>A B C </Section>
<Number>08082018</Number>
<Format>
<Height>21.70i</Height>
<Width>9.87i</Width>
</Format>
<PrintingInfo/>
<Version/>
<Config/>
<Default/>
<FileFormat>2.0</FileFormat>
<IssueName/>
</Header>
<Page>
<PhysicalBook>A</PhysicalBook>
<BookPageNumber>1</BookPageNumber>
<Desk>A</Desk>
<SubDesk/>
<SpreadPage>0</SpreadPage>
<Status/>
<Deadline>0708182230</Deadline>
<PagePrintInfo/>
<Cmyk>CMYK</Cmyk>
<Spot1/>
<Spot2/>
<Spot3/>
<CyanFilm/>
<MagFilm/>
<YelFilm/>
<BlackFilm/>
<Spot1Film/>
<Spot2Film/>
<Spot3Film/>
<PageId>MAIN#F</PageId>
<TemplatePage>
<Content>c#FolioStandard#i#</Content>
<Layout></Layout>
</TemplatePage>
<ProdForm/>
<TextSourceDir/>
<TextSourcePage/>
<RunningPage/>
<CmyDeadline/>
<ColorGrp/>
<AdRules>1</AdRules>
<CustChar/>
<CustDate/>
<Active>1</Active>
<NoMaster>0</NoMaster>
<Cust2/>
<PageType>EditorialOnly</PageType>
<Cust4/>
<Cust5/>
<Cust6/>
<Cust7/>
<Cust8/>
<Cust9/>
<Cust10/>
<Desk2/>
<Desk2NewsHole/>
<Desk2Placement/>
<Cust11/>
<NotUsed2/>
<NotUsed3/>
<Ad>
<BookingNumber>12345</BookingNumber>
<Description>Desc1</Description>
<AdRelatedInfo> </AdRelatedInfo>
<FirstPubDate>080818</FirstPubDate>
<LastPubDate>080818</LastPubDate>
<Customer>Customer</Customer>
<AdColor>Proces</AdColor>
<AdWidth>710.9</AdWidth>
<AdHeight>144.0</AdHeight>
<MatType>EPS</MatType>
<AdType>0</AdType>
<AdPos>
<XPos>0.00</XPos>
<YPos>1404.03</YPos>
</AdPos>
<AdProdInfo/>
<AdNotUsed2/>
<AdNotUsed3/>
<AdCust1/>
<AdCust2/>
<AdCust3/>
</Ad>
<AutoTypesetInfo>0:5-60</AutoTypesetInfo></Page>
<Page>
<PhysicalBook>A</PhysicalBook>
<BookPageNumber>2</BookPageNumber>
<Desk>A</Desk>
<SubDesk/>
<SpreadPage>0</SpreadPage>
<Status/>
<Deadline>0708182230</Deadline>
<PagePrintInfo/>
<Cmyk>CMYK</Cmyk>
<Spot1/>
<Spot2/>
<Spot3/>
<CyanFilm/>
<MagFilm/>
<YelFilm/>
<BlackFilm/>
<Spot1Film/>
<Spot2Film/>
<Spot3Film/>
<PageId>MAIN#1</PageId>
<TemplatePage>
<Content>c#FolioStandard#i#</Content>
<Layout></Layout>
</TemplatePage>
<ProdForm/>
<TextSourceDir/>
<TextSourcePage/>
<RunningPage/>
<CmyDeadline/>
<ColorGrp/>
<AdRules>1</AdRules>
<CustChar/>
<CustDate/>
<Active>1</Active>
<NoMaster>0</NoMaster>
<Cust2/>
<PageType>Mixed</PageType>
<Cust4/>
<Cust5/>
<Cust6/>
<Cust7/>
<Cust8/>
<Cust9/>
<Cust10/>
<Desk2/>
<Desk2NewsHole/>
<Desk2Placement/>
<Cust11/>
<NotUsed2/>
<NotUsed3/>
<Ad>
<BookingNumber>152345</BookingNumber>
<Description>Description</Description>
<AdRelatedInfo> </AdRelatedInfo>
<FirstPubDate>080818</FirstPubDate>
<LastPubDate>080818</LastPubDate>
<Customer>Customer</Customer>
<AdColor>000K</AdColor>
<AdWidth>351.9</AdWidth>
<AdHeight>360.0</AdHeight>
<MatType>EPS</MatType>
<AdType>0</AdType>
<AdPos>
<XPos>0.00</XPos>
<YPos>1188.03</YPos>
</AdPos>
<AdProdInfo/>
<AdNotUsed2/>
<AdNotUsed3/>
<AdCust1/>
<AdCust2/>
<AdCust3/>
</Ad>
<Ad>
<BookingNumber>12345</BookingNumber>
<Description>Description</Description>
<AdRelatedInfo> </AdRelatedInfo>
<FirstPubDate>080818</FirstPubDate>
<LastPubDate>080818</LastPubDate>
<Customer>Customer</Customer>
<AdColor>Proces</AdColor>
<AdWidth>351.9</AdWidth>
<AdHeight>360.0</AdHeight>
<MatType>EPS</MatType>
<AdType>0</AdType>
<AdPos>
<XPos>358.99</XPos>
<YPos>1188.03</YPos>
</AdPos>
<AdProdInfo/>
<AdNotUsed2/>
<AdNotUsed3/>
<AdCust1/>
<AdCust2/>
<AdCust3/>
</Ad>
<AutoTypesetInfo>0:5-60</AutoTypesetInfo>
</Page>
</Plan>
XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:cci="http://www.ccieurope.com/xmlns/CCIPlanner"
exclude-result-prefixes="msxsl cci"
>
<xsl:output indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!-- If element name match on NotUsed2, exclude from result -->
<xsl:template match="NotUsed2" />
</xsl:stylesheet>
Expected in the resulting Page node:
<Page>
<PhysicalBook>A</PhysicalBook>
<BookPageNumber>1</BookPageNumber>
<Desk>A</Desk>
<SubDesk/>
<SpreadPage>0</SpreadPage>
<Status/>
<Deadline>0708182230</Deadline>
<PagePrintInfo/>
<Cmyk>CMYK</Cmyk>
<Spot1/>
<Spot2/>
<Spot3/>
<CyanFilm/>
<MagFilm/>
<YelFilm/>
<BlackFilm/>
<Spot1Film/>
<Spot2Film/>
<Spot3Film/>
<PageId>MAIN#F</PageId>
<TemplatePage>
<Content>c#FolioStandard#i#</Content>
<Layout></Layout>
</TemplatePage>
<ProdForm/>
<TextSourceDir/>
<TextSourcePage/>
<RunningPage/>
<CmyDeadline/>
<ColorGrp/>
<AdRules>1</AdRules>
<CustChar/>
<CustDate/>
<Active>1</Active>
<NoMaster>0</NoMaster>
<Cust2/>
<PageType>EditorialOnly</PageType>
<Cust4/>
<Cust5/>
<Cust6/>
<Cust7/>
<Cust8/>
<Cust9/>
<Cust10/>
<Desk2/>
<Desk2NewsHole/>
<Desk2Placement/>
<Cust11/>
<NotUsed3/>
<AutoTypesetInfo>0:5-60</AutoTypesetInfo>
<Ad>
<BookingNumber>12345</BookingNumber>
<Description>Desc1</Description>
<AdRelatedInfo> </AdRelatedInfo>
<FirstPubDate>080818</FirstPubDate>
<LastPubDate>080818</LastPubDate>
<Customer>Customer</Customer>
<AdColor>Proces</AdColor>
<AdWidth>710.9</AdWidth>
<AdHeight>144.0</AdHeight>
<MatType>EPS</MatType>
<AdType>0</AdType>
<AdPos>
<XPos>0.00</XPos>
<YPos>1404.03</YPos>
</AdPos>
<AdProdInfo/>
<AdNotUsed2/>
<AdNotUsed3/>
<AdCust1/>
<AdCust2/>
<AdCust3/>
</Ad>
</Page>
I can't get the code to exclude the NotUsed2 element.
I'm not sure where to begin to tackle reordering the elements within nodes.
Any help would be appreciated.
Your NotUsed2 is not being removed because you have not accounted for the fact the element is in a default namespace in the XML. Your XSLT is looking for an element with no namespace.
You have declared the relevant namespace in your XSLT, so you just need to use the relevant prefix in the template match
<xsl:template match="cci:NotUsed2" />
For moving AutoTypesetInfo after NotUsed3 you should have a template that matches NotUsed3 where you can copy both the matched node, and the AutoTypesetInfo
<xsl:template match="cci:NotUsed3">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
<xsl:copy-of select="../cci:AutoTypesetInfo" />
</xsl:template>
You would also need a template to ensure the AutoTypesetInfo still doesn't get copied in its current position too
<xsl:template match="cci:AutoTypesetInfo" />
Try this XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:cci="http://www.ccieurope.com/xmlns/CCIPlanner"
exclude-result-prefixes="msxsl cci">
<xsl:output indent="yes"/>
<xsl:template match="#* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!-- If element name match on NotUsed2, exclude from result -->
<xsl:template match="cci:NotUsed2" />
<xsl:template match="cci:NotUsed3">
<xsl:call-template name="identity" />
<xsl:copy-of select="../cci:AutoTypesetInfo" />
</xsl:template>
<xsl:template match="cci:AutoTypesetInfo" />
</xsl:stylesheet>
This does assume NotUsed3 is always present. If not, change the last template to this to ensure the original AutoTypesetInfo is not removed in this case.
<xsl:template match="cci:AutoTypesetInfo[../cci:NotUsed3]" />
Try below XSLT.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:cci="http://www.ccieurope.com/xmlns/CCIPlanner"
exclude-result-prefixes="msxsl cci"
>
<xsl:output indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!-- If element name match on NotUsed2, exclude from result -->
<xsl:template match="*[local-name()='NotUsed2']" />
</xsl:stylesheet>

XSLT - Copy all nodes and add extra node in copied nodes

I am looking for XSLT(1.0) code for below input and output XML.
In output XML, there can be any child node under C6 element. In below XML, i have put CN element but it could be any name.
Input XML -
<?xml version = "1.0" encoding = "UTF-8"?>
<root>
<input>
<c2>
<c3>
<c4>c4</c4>
</c3>
</c2>
</input>
<output>
<c5>
<c6>
<CN>
<T1></T1>
<T2></T2>
</CN>
</c6>
<c6>
<CN>
<T1></T1>
<T2></T2>
</CN>
</c6>
</c5>
</output>
</root>
Desired Output XML-
<root>
<output>
<c5>
<c6>
<!-- It could have any child node. Putting an example with CN child node name.-->
<CN>
<T1></T1>
<T2></T2>
<c3>
<c4>c4</c4>
<NewNode>current number of CN node which will be 1</NewNode>
<NewNode1>total number of C6 nodes which will be 2.</NewNode1>
</c3>
</CN>
</c6>
<c6>
<CN>
<T1></T1>
<T2></T2>
<c3>
<c4>c4</c4>
<NewNode>current number of CN node which will be 2</NewNode>
<NewNode1>total number of C6 nodes which will be 2.</NewNode1>
</c3>
</CN>
</c6>
</c5>
</output>
</root>
Thank you in advance.
Use the following stylesheet:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="c6/*">
<xsl:copy>
<xsl:variable name="v1" select="count(../preceding-sibling::*)+1"/>
<xsl:variable name="v2" select="count(../../*)"/>
<xsl:apply-templates/>
<xsl:apply-templates select="../../../../input/c2/c3">
<xsl:with-param name="v1" select="$v1"/>
<xsl:with-param name="v2" select="$v2"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="c3">
<xsl:param name="v1"/>
<xsl:param name="v2"/>
<xsl:copy>
<xsl:apply-templates/>
<NewNode><xsl:value-of select="$v1"/></NewNode>
<NewNode1><xsl:value-of select="$v2"/></NewNode1>
</xsl:copy>
</xsl:template>
<xsl:template match="input"/>
<xsl:template match="#*|node()">
<xsl:copy><xsl:apply-templates select="#*|node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>

In XSLT replace value

I have this XML document :Now I want to replace LineNo so that the output will be line no will 1 ,2 . I have tried some thing like this.
<xsl:value-of select="replace( '000010',1)"/>
<Rder>
<Order>
<OrderNo>458</OrderNo>
<LineNo>000010</LineNo>
<SerialNO>96</SerialNO>
<VNo>543</VNo>
</Order>
<Order>
<OrderNo>458</OrderNo>
<LineNo>000020</LineNo>
<SerialNO>32</SerialNO>
<VNo>543</VNo>
</Order>
</Rder>
I want to replace the value of LineNo= 000010 ,000020 by 1,2 in XSLT below one i have tried.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="orders" match="Order" use="OrderNo" />
<xsl:template match="/*">
<SalesOrders>
<xsl:for-each select="Rder/Order[generate-id() = generate-id(key('orders', OrderNo)[1])]">
<Order VNo="{VNo}" OrderNo="{OrderNo}">
<OrderLines>
<xsl:apply-templates select="key('orders', OrderNo)" />
</OrderLines>
</Order>
</xsl:for-each>
</SalesOrders>
</xsl:template>
<xsl:template match="Order">
<OrderLine LineNo="{LineNo}" SerialNO="{SerialNO}"/>
</xsl:template>
</xsl:stylesheet>
Actually I getting those lineno details in same format i have tried couple cases its doesn't giving that expected format.
Any help would be appreciated.
Why don't you do simply:
<xsl:template match="Order">
<OrderLine LineNo="{position()}" SerialNO="{SerialNO}"/>
</xsl:template>
or:
<xsl:template match="Order">
<OrderLine LineNo="{number(LineNo) div 10}" SerialNO="{SerialNO}"/>
</xsl:template>

Remove parent based on child value?

I want to display only those orders which dont have OrderLineSource = YTR. All other should be displayed....
My Sample XML :
<Orders>
<Order>
<OrderID>34209649</OrderID>
<OrderStatus>checkout_complete</OrderStatus>
<Amount>32.93</Amount>
<OrderCreation>2014-02-08T00:00:03.00</OrderCreation>
<OrderCompletion>2014-02-08T00:00:03.00</OrderCompletion>
<CustomerGUID>303965683</CustomerGUID>
<CSMPurchaserGUID>0</CSMPurchaserGUID>
<Brand>TRFE</Brand>
<SourceECommerceSystem>Framework</SourceECommerceSystem>
<Currency>GBP</Currency>
<OrderChannel>Online</OrderChannel>
<TransactionSummary>
<TransactionID>2407065</TransactionID>
<MerchantReference>TEdV-5648-34209649</MerchantReference>
<CardCategory>Personal</CardCategory>
<CardScheme>VISA Debit</CardScheme>
<CardCountry>gbr</CardCountry>
<CardIssuer>sdfsdf sdf Bank asdf</CardIssuer>
<CardStartDate>0/0</CardStartDate>
<CardExpiryDate>2016/08</CardExpiryDate>
<Amount>32.93</Amount>
<Currency>GBP</Currency>
<CardPAN>************4585</CardPAN>
<Created>2014-02-07T23:56:48</Created>
<Updated>2014-02-08T00:00:03</Updated>
<ResponseStatusCode>1</ResponseStatusCode>
<ResponseStatusReason>FULFILLED OK</ResponseStatusReason>
<HostedPageIdentifier>dsfasdf-ee85-4afa-bb6a-0afc6dc99896</HostedPageIdentifier>
<HostedPageURL>https://hps.datacash.com/hps/</HostedPageURL>
<PaymentStatus>Paid</PaymentStatus>
<PaymentType>Debit Card</PaymentType>
<NameOnCard>Miss L J adsf</NameOnCard>
<DataCashRef>56456456454</DataCashRef>
<MerchantID>545646</MerchantID>
<ThreeDCard>1</ThreeDCard>
<ThreeDRequested>1</ThreeDRequested>
<IPAddress>127.89.560.1</IPAddress>
</TransactionSummary>
<OrderLine>
<OrderLineID>84598837</OrderLineID>
<OrderID>34209649</OrderID>
<OrderLineLabel>GAREGSBV</OrderLineLabel>
<OrderLineSource>GHR</OrderLineSource>
<Quantity>1</Quantity>
<UnitPrice>32.93</UnitPrice>
<Total>32.93</Total>
<SKUCode>P0032</SKUCode>
<Title>Miss.</Title>
<FirstName>ertwer</FirstName>
<FamilyName>sdaf</FamilyName>
<DateOfBirth>1984-05-30</DateOfBirth>
<Email>sdfasdfa#hotmail.com</Email>
<Mobile>645646454</Mobile>
<PostChannel>0</PostChannel>
<TelephoneChannel>0</TelephoneChannel>
<EmailChannel>0</EmailChannel>
<TextAndOtherChannel>0</TextAndOtherChannel>
<BuildingNumber>27</BuildingNumber>
<AddressLine1>27</AddressLine1>
<AddressLine2>dsfasdf Road</AddressLine2>
<Town>London</Town>
<Country>sdfasdf er</Country>
<Postcode>KL7 2NS</Postcode>
<AddressValidated>1</AddressValidated>
<HKPolicy>
<PolicyNum>PP01754397</PolicyNum>
<ProductDescription>sadfsadfasdfgasdg</ProductDescription>
<CoverTypeDesc>Individual</CoverTypeDesc>
<SingleParentFamilyFlag>0</SingleParentFamilyFlag>
<PolicyTypeRefID>S</PolicyTypeRefID>
<PolicyTypeDesc>Sinasdfnce</PolicyTypeDesc>
<TierDesc>Classic</TierDesc>
<DestinationDesc>Worldwide including USA, Canada, Caribbean</DestinationDesc>
<TotalTravellers>1</TotalTravellers>
<NumOfAdults>1</NumOfAdults>
<NumOfUnder18>0</NumOfUnder18>
<PolicyStartDate>2014-02-08</PolicyStartDate>
<PolicyEndDate>2014-02-12</PolicyEndDate>
<BaseCost>32.93</BaseCost>
<Commission>11.18</Commission>
<UpsoldInd>0</UpsoldInd>
<TierRefID>C</TierRefID>
<DestinationRefID>W2</DestinationRefID>
<CoverTypeRefID>I</CoverTypeRefID>
<AONToPostPolicy>yes</AONToPostPolicy>
<SalesChannel>0011002</SalesChannel>
<WhereYouHeardOfUs>Press advertising</WhereYouHeardOfUs>
<TIPOLTraveller>
<TravellerUUID>1864-1</TravellerUUID>
<PolicyNum>PI0e31754397</PolicyNum>
<Title>Miss</Title>
<FirstName>sdfsf</FirstName>
<FamilyName>sdfsdf</FamilyName>
<DateOfBirth>1984-05-30</DateOfBirth>
<AgeBand>1864</AgeBand>
<DependentFlag>0</DependentFlag>
</TIPOLTraveller>
</TIPOLPolicy>
</OrderLine>
<OrderCustomerDetails>
<Title nil="true" />
<FirstName nil="true" />
<SecondName nil="true" />
<FamilyName nil="true" />
<DateOfBirth nil="true" />
<Email nil="true" />
<Telephone nil="true" />
<Mobile nil="true" />
<Gender nil="true" />
<PostChannel nil="true" />
<TelephoneChannel nil="true" />
<EmailChannel nil="true" />
<TextAndOtherChannel nil="true" />
<BuildingNumber>27</BuildingNumber>
<AddressLine1>27</AddressLine1>
<AddressLine2>asdfa Road</AddressLine2>
<Town>asdfasdf</Town>
<Country>United dsf</Country>
<Postcode>KH9 2NS</Postcode>
<AddressValidated>1</AddressValidated>
</OrderCustomerDetails>
</Order>
<Order>
<OrderID>34209674</OrderID>
<OrderStatus>checkout_complete</OrderStatus>
<Amount>11.13</Amount>
<OrderCreation>2014-02-08T00:08:40.00</OrderCreation>
<OrderCompletion>2014-02-08T00:08:40.00</OrderCompletion>
<CustomerGUID>303965688</CustomerGUID>
<CSMPurchaserGUID>0</CSMPurchaserGUID>
<Brand>TRFDS</Brand>
<SourceECommerceSystem>Framework</SourceECommerceSystem>
<Currency>GBP</Currency>
<OrderChannel>Online</OrderChannel>
<TransactionSummary>
<TransactionID>8115032</TransactionID>
<MerchantReference>JHF-0800-34209674</MerchantReference>
<CardCategory>Personal</CardCategory>
<CardScheme>VISA Debit</CardScheme>
<CardCountry>gbr</CardCountry>
<CardIssuer>Unknown</CardIssuer>
<CardStartDate>0/0</CardStartDate>
<CardExpiryDate>2016/09</CardExpiryDate>
<Amount>11.13</Amount>
<Currency>GBP</Currency>
<CardPAN>************4849</CardPAN>
<Created>2014-02-08T00:08:00</Created>
<Updated>2014-02-08T00:08:40</Updated>
<ResponseStatusCode>1</ResponseStatusCode>
<ResponseStatusReason>FULFILLED OK</ResponseStatusReason>
<HostedPageIdentifier>f3306487-d6ea-4200-9eea-99b1d6832a2e</HostedPageIdentifier>
<HostedPageURL>https://hps.dat.com/hps/</HostedPageURL>
<PaymentStatus>Paid</PaymentStatus>
<PaymentType>Debit Card</PaymentType>
<NameOnCard>Miss Jor </NameOnCard>
<DataCashRef>380010093738013</DataCashRef>
<MerchantID>21877049</MerchantID>
<ThreeDCard>1</ThreeDCard>
<ThreeDRequested>1</ThreeDRequested>
<IPAddress>86..25640.99</IPAddress>
</TransactionSummary>
<OrderLine>
<OrderLineID>84598874</OrderLineID>
<OrderID>34209674</OrderID>
<OrderLineLabel>3-1008617753325</OrderLineLabel>
<OrderLineSource>YTR</OrderLineSource>
<Quantity>1</Quantity>
<UnitPrice>11.13</UnitPrice>
<Total>11.13</Total>
<Title>Miss.</Title>
<FirstName>Jordan</FirstName>
<SecondName>oirut</SecondName>
<FamilyName>dfgsdfgs</FamilyName>
<Email>dfgsdfg#hotmail.com</Email>
<Mobile>654756464</Mobile>
<PostChannel>0</PostChannel>
<TelephoneChannel>0</TelephoneChannel>
<EmailChannel>0</EmailChannel>
<TextAndOtherChannel>0</TextAndOtherChannel>
<BuildingNumber>12</BuildingNumber>
<AddressLine1>12</AddressLine1>
<AddressLine2>sfgsdfg End Gardens</AddressLine2>
<Town>HEMEL sfgaefa</Town>
<Country>adf dgfsdfg</Country>
<Postcode>HP1 1SN</Postcode>
<OrderLineDetail>
<NameValuePair>
<Name>dfgsdfg</Name>
<Value>628</Value>
</NameValuePair>
<NameValuePair>
<Name>NameOnCard</Name>
<Value>adsfgasdgf Piper</Value>
</NameValuePair>
<NameValuePair>
<Name>DateOnCard</Name>
<Value>2014-02-05</Value>
</NameValuePair>
<NameValuePair>
<Name>CustomsOrSurcharge</Name>
<Value>CUSTOMS CHARGE TO PAY</Value>
</NameValuePair>
</OrderLineDetail>
</OrderLine>
<OrderCustomerDetails>
<Title>Miss.</Title>
<FirstName>Jordan</FirstName>
<SecondName>asdgfasdgf</SecondName>
<FamilyName nil="true" />
<DateOfBirth />
<Email>adfadf#hotmail.com</Email>
<Telephone />
<Mobile>adfasdf</Mobile>
<Gender nil="true" />
<PostChannel nil="true" />
<TelephoneChannel nil="true" />
<EmailChannel nil="true" />
<TextAndOtherChannel nil="true" />
<BuildingNumber>12</BuildingNumber>
<AddressLine1>12</AddressLine1>
<AddressLine2>adfasdf End Gardens</AddressLine2>
<Town>adsfasdf HEMPSTEAD</Town>
<Country>United asdfasdf</Country>
<Postcode>asd 1SN</Postcode>
</OrderCustomerDetails>
</Order>
</Orders>
I tried using XSLT :
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<!-- Orders -->
<xsl:template match="/*">
<xsl:element name="Orders">
<xsl:apply-templates select="./Order" />
</xsl:element>
</xsl:template>
<!-- Orders > Order -->
<xsl:template match="/Order">
<xsl:variable name="IsValid">
<xsl:call-template name="HasOrIsValidPOLine" />
</xsl:variable>
<xsl:if test="$IsValid='VALID'"> <!-- only display the order if there's a valid line under it-->
<xsl:element name="Order">
<xsl:apply-templates select=".//VORNR" />
</xsl:element>
</xsl:if>
</xsl:template>
<!-- Part Order List > Part Order > Operational BO Number -->
<xsl:template match="//VORNR">
<xsl:element name="./Order">
<xsl:apply-templates select="node()|#*"/>
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:template>
<xsl:template name="HasOrIsValidPOLine">
<xsl:choose>
<xsl:when test="./OrderLineSource/text() != 'YTR'">VALID</xsl:when>
<xsl:otherwise>INVALID</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Can you provide me the solution or let me know where I am going wrong
First, your sample XML is not well-formed: It contains a closing </TIPOLPolicy> tag that doesn't match the starting <HKPolicy> tag. Change that to </HKPolicy> first.
After that, the following XSLT 1.0 does what you want:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- Identity transform -->
<!-- Default priority 0 for root node and -0.5 for the rest -->
<xsl:template match="/ | node() | #*">
<xsl:copy>
<xsl:apply-templates select="node() | #*"/>
</xsl:copy>
</xsl:template>
<!-- Do nothing for Order elements whose OrderLine/OrderLineSource equals 'YTR' -->
<!-- Default priority 0.5 -->
<xsl:template match="Order[OrderLine/OrderLineSource = 'YTR']"/>
</xsl:stylesheet>
It makes use of the identity transform and different default priorities: The identity transform with a lower default priority copies the input to the output unless another template with a higher priority exists for a given input match. This is the case for Order elements whose OrderLine/OrderLineSource descendant contains the text value 'YTR'. Due to its higher default priority, the more specific template takes precedence over the identity transform. Since the template doesn't produce any output, any matching Order elements are removed from the output.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Order[OrderLine/OrderLineSource[string() = 'YTR']]"/>
</xsl:stylesheet>