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

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>

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.

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>

Sort the info based on given sequence order

Please suggest how to sort the info, based on given sort sequence (Seq.xml).
Here fetching info from folder where files' name should have 'Sort##.xml' formats. Output should be sort based on DOI number as sequnce given in external file 'D:\Sort\Seq.xml'.
Input XMLs:
D:\Sort\Sort01.xml
<article>
<fm>
<title>The solar system</title>
<aug><au>Rudramuni TP</au></aug>
<doi>10.11/MPS.0.10.11</doi>
</fm>
<body><text>The text</text></body>
</article>
D:\Sort\Sort02.xml
<article>
<fm>
<title>The Galaxy</title>
<aug><au>Kishan TR</au></aug>
<doi>10.11/MPS.0.10.2</doi>
</fm>
<body><text>The text</text></body>
</article>
D:\Sort\Sort03.xml
<article>
<fm>
<title>The Pluto</title>
<aug><au>Kowshik MD</au></aug>
<doi>10.11/MPS.0.10.10</doi>
</fm>
<body><text>The text</text></body>
</article>
Sequence info in D:\Sort\Seq.xml
<root>
<toc>
<seq seq="1"><art-id>10.11/MPS.0.10.2</art-id></seq>
<seq seq="2"><art-id>10.11/MPS.0.10.11</art-id></seq>
<seq seq="3"><art-id>10.11/MPS.0.10.10</art-id></seq>
</toc>
</root>
XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:variable name="varCollection">
<xsl:copy-of select="
collection('file:///D:/Sort/?select=Sort*.xml; recurse=yes')
[matches(document-uri(.),'Sort/Sort[0-9][0-9].xml')]"/>
</xsl:variable><!-- to fetch info from folder 'Sort*.xml' s -->
<xsl:variable name="docSeq" select="document('D:/Sort/Seq.xml')"/><!--In this file, sequnce info is there -->
<!--xsl:key name="kSeq" match="$docSeq/root/toc/seq/#seq" use="art-id"/--><!-- I tried with key, but unable to get the required sequence -->
<xsl:template match="root">
<xsl:for-each select="$varCollection/article">
<!--xsl:sort select="key('kSeq', fm/doi)"/-->
<art>
<title><xsl:value-of select="fm/title"/></title>
<Name><xsl:value-of select="fm/aug/au"/></Name>
<DOI><xsl:value-of select="fm/doi"/></DOI>
</art><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Required Sequence
<art><title>The Galaxy</title><Name>Kishan TR</Name><DOI>10.11/MPS.0.10.2</DOI></art>
<art><title>The solar system</title><Name>Rudramuni TP</Name><DOI>10.11/MPS.0.10.11</DOI></art>
<art><title>The Pluto</title><Name>Kowshik MD</Name><DOI>10.11/MPS.0.10.10</DOI></art>
I think you want
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="varCollection" select="
collection('file:///D:/Sort/?select=Sort*.xml; recurse=yes')
[matches(document-uri(.),'Sort/Sort[0-9][0-9].xml')]"/>
<xsl:variable name="docSeq" select="document('file:///D:/Sort/Seq.xml')"/><!--In this file, sequnce info is there -->
<xsl:key name="kSeq" match="root/toc/seq" use="art-id"/>
<xsl:template match="root">
<xsl:for-each select="$varCollection/article">
<xsl:sort select="key('kSeq', fm/doi, $docSeq)/xs:integer(#seq)"/>
<art>
<title><xsl:value-of select="fm/title"/></title>
<Name><xsl:value-of select="fm/aug/au"/></Name>
<DOI><xsl:value-of select="fm/doi"/></DOI>
</art>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
You could also do this from the opposite direction:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:variable name="varCollection">
<xsl:sequence select="collection('file:///D:/Sort/?select=Sort*.xml; recurse=yes')
[matches(document-uri(.),'Sort/Sort[0-9][0-9].xml')]"/>
</xsl:variable>
<xsl:variable name="docSeq" select="document('D:/Sort/Seq.xml')"/>
<xsl:key name="article" match="article" use="fm/doi" />
<xsl:template match="root">
<xsl:for-each select="$docSeq/root/toc/seq">
<xsl:sort select="#seq" data-type="number" order="ascending"/>
<xsl:apply-templates select="key('article', art-id, $varCollection)"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="article">
<art>
<title><xsl:value-of select="fm/title"/></title>
<Name><xsl:value-of select="fm/aug/au"/></Name>
<DOI><xsl:value-of select="fm/doi"/></DOI>
</art>
</xsl:template>
</xsl:stylesheet>
Note that the output lacks a root element.

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>

Trying to expand data using XSLT

I am an admitted novice with XSLT and am looking for some direction. I have the follow (simplified) XML input data. I want to take the underlying data and apply it to AccountExternalSystemId or flatten it out.
<?xml version="1.0" ?>
<ns:CustomObject3WS_CustomObject3QueryPage_Output xmlns:ns="urn:crmondemand/ws/customobject3/10/2004">
<ns:LastPage>true</ns:LastPage>
<ListOfCustomObject3 xmlns="urn:/crmondemand/xml/customObject3">
<CustomObject3>
<AccountExternalSystemId>A000008351</AccountExternalSystemId>
<ListOfAccount>
<Account>
<AccountId>AAXA-H72YN</AccountId>
<ExternalSystemId>100000000002795</ExternalSystemId>
<Name>CATERPILLAR INC [100000000002795]</Name>
</Account>
<Account>
<AccountId>ADOA-3BAK0F</AccountId>
<ExternalSystemId>A000008351</ExternalSystemId>
<Name>CATERPILLAR</Name>
</Account>
</ListOfAccount>
</CustomObject3>
<CustomObject3>
<AccountExternalSystemId>100000000001059</AccountExternalSystemId>
<ListOfAccount>
<Account>
<AccountId>AAXA-H0B7N</AccountId>
<ExternalSystemId>100000000001059</ExternalSystemId>
<Name>SERV SA [100000000001059]</Name>
</Account>
</ListOfAccount>
</CustomObject3>
</ListOfCustomObject3>
I am applying the following XSL to the data:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="*:CustomObject3WS_CustomObject3QueryPage_Output"/>
</xsl:template>
<xsl:template match="*:CustomObject3WS_CustomObject3QueryPage_Output">
<xsl:copy>
<xsl:apply-templates select="*:LastPage"/>
<xsl:apply-templates select="*:ListOfCustomObject3"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*:ListOfCustomObject3">
<xsl:copy>
<xsl:apply-templates select="*:CustomObject3"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*:CustomObject3">
<xsl:variable select="*:AccountExternalSystemId" name="AccountExternalSystemId"/>
<xsl:copy>
<xsl:for-each select="*:ListOfAccount/*:Account">
<xsl:element name="AccountId" namespace="urn:/crmondemand/xml/customObject3"><xsl:value-of select="substring(*:AccountId,1,15)"/></xsl:element>
<xsl:element name="AccountName" namespace="urn:/crmondemand/xml/customObject3"><xsl:value-of select="substring(*:Name,1,255)"/></xsl:element>
<xsl:element name="AccountExternalSystemId" namespace="urn:/crmondemand/xml/customObject3"><xsl:value-of
select="substring($AccountExternalSystemId,1,64)"/></xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
and here is my result (you can see that CustomObject3 is not properly ended (as there should be 2) in the first example. Not sure if my approach is the best way to accomplish what I need to do:
<?xml version="1.0" encoding="UTF-8"?>
<ns:CustomObject3WS_CustomObject3QueryPage_Output>
<ns:LastPage>true</ns:LastPage>
<ListOfCustomObject3 xmlns="urn:/crmondemand/xml/customObject3">
<CustomObject3>
<AccountId>AAXA-H72YN</AccountId>
<AccountName>CATERPILLAR INC [100000000002795]</AccountName>
<AccountExternalSystemId>A000008351</AccountExternalSystemId>
<AccountId>ADOA-3BAK0F</AccountId>
<AccountName>CATERPILLAR</AccountName>
<AccountExternalSystemId>A000008351</AccountExternalSystemId>
</CustomObject3>
<CustomObject3>
<AccountId>AAXA-H0B7N</AccountId>
<AccountName>SERV SA [100000000001059]</AccountName>
<AccountExternalSystemId>100000000001059</AccountExternalSystemId>
</CustomObject3>
</ListOfCustomObject3>
The desired output would be:
<?xml version="1.0" encoding="UTF-8"?>
<ns:CustomObject3WS_CustomObject3QueryPage_Output>
<ns:LastPage>true</ns:LastPage>
<ListOfCustomObject3 xmlns="urn:/crmondemand/xml/customObject3">
<CustomObject3>
<AccountId>AAXA-H72YN</AccountId>
<AccountName>CATERPILLAR INC [100000000002795]</AccountName>
<AccountExternalSystemId>A000008351</AccountExternalSystemId>
</CustomObject3>
<CustomObject3>
<AccountId>ADOA-3BAK0F</AccountId>
<AccountName>CATERPILLAR</AccountName>
<AccountExternalSystemId>A000008351</AccountExternalSystemId>
</CustomObject3>
<CustomObject3>
<AccountId>AAXA-H0B7N</AccountId>
<AccountName>SERV SA [100000000001059]</AccountName>
<AccountExternalSystemId>100000000001059</AccountExternalSystemId>
</CustomObject3>
Remark note that the output in your question presents a prefix (ns:) not bound to any namespace declaration.
Look at this direction:
where identity.xsl is the well known Identity Transformation
default namespaces are handled in a simpler way
produced output has the correct namespace declarations
[XSLT 2.0]
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns="urn:/crmondemand/xml/customObject3"
xpath-default-namespace="urn:/crmondemand/xml/customObject3">
<xsl:output indent="yes"/>
<xsl:include href="identity.xsl"/>
<xsl:template match="CustomObject3">
<xsl:apply-templates select="ListOfAccount/Account"/>
</xsl:template>
<xsl:template match="Account">
<CustomObject3>
<xsl:apply-templates select="AccountId|Name"/>
<xsl:copy-of select="../../AccountExternalSystemId"/>
</CustomObject3>
</xsl:template>
<xsl:template match="Name">
<xsl:element name="Account{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
gives wanted output (with correct namespace declarations):
<ns:CustomObject3WS_CustomObject3QueryPage_Output xmlns:ns="urn:crmondemand/ws/customobject3/10/2004">
<ns:LastPage>true</ns:LastPage>
<ListOfCustomObject3 xmlns="urn:/crmondemand/xml/customObject3">
<CustomObject3>
<AccountId>AAXA-H72YN</AccountId>
<AccountName>CATERPILLAR INC [100000000002795]</AccountName>
<AccountExternalSystemId>A000008351</AccountExternalSystemId>
</CustomObject3>
<CustomObject3>
<AccountId>ADOA-3BAK0F</AccountId>
<AccountName>CATERPILLAR</AccountName>
<AccountExternalSystemId>A000008351</AccountExternalSystemId>
</CustomObject3>
<CustomObject3>
<AccountId>AAXA-H0B7N</AccountId>
<AccountName>SERV SA [100000000001059]</AccountName>
<AccountExternalSystemId>100000000001059</AccountExternalSystemId>
</CustomObject3>
</ListOfCustomObject3>
</ns:CustomObject3WS_CustomObject3QueryPage_Output>