Adding new XML elements using XSLT - xslt

I have the requirement in which I need to add the new elements. Can anyone please help where I am doing it wrong? I have attached the sample input, sample output and I have attached the code I am using as well :)
Sample Input:
<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<OrderCreate Version="5.1.1" xmlns="urn:midx:names:specification:ces:schema:all:5:1:1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<ThisDocumentIdentifier>
<DocumentIdentifier>58585993</DocumentIdentifier>
</ThisDocumentIdentifier>
<ThisDocumentDateTime>
<DateTime DateTimeQualifier="On">2014-08-22T00:00:00Z</DateTime>
</ThisDocumentDateTime>
<From>
<PartnerInformation>
<PartnerName>MOSLLC</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0089646370000</PartnerIdentifier>
<ContactInformation>
<ContactName>MOSLLC </ContactName>
<ContactName>804-281-1402</ContactName>
<EmailAddress></EmailAddress>
</ContactInformation>
</PartnerInformation>
</From>
<To>
<PartnerInformation>
<PartnerName>Walmart</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0062668030000</PartnerIdentifier>
</PartnerInformation>
</To>
</Header>
<OrderCreateBody>
<OrderCreateProperties>
<PurchaseOrderNumber>
<DocumentIdentifier>OD3157538</DocumentIdentifier>
</PurchaseOrderNumber>
<PurchaseOrderTypeCode Domain="ANSI-ASC-X12-92">KN</PurchaseOrderTypeCode>
<PurchaseOrderIssuedDate>
<DateTime DateTimeQualifier="On">2014-08-22T00:00:00Z</DateTime>
</PurchaseOrderIssuedDate>
<LanguageCode Domain="ISO-639-2T">eng</LanguageCode>
<CurrencyCode Domain="ISO-4217">USD</CurrencyCode>
<BuyerSequenceNumber>0</BuyerSequenceNumber>
<DeliveryTerms>
<DeliveryTermsCode Domain="Incoterms-2000">CPT</DeliveryTermsCode>
<DeliveryTermsLocation>ORIGIN</DeliveryTermsLocation>
</DeliveryTerms>
<ShipmentMethodOfPaymentCode Domain="ANSI-ASC-X12-146">PC</ShipmentMethodOfPaymentCode>
<PaymentTerms>
<PaymentTermsOfSale>
<TermsOfSaleDescription>DUE 25TH OF FOLLOWING MONTH</TermsOfSaleDescription>
<NetDaysDue>0</NetDaysDue>
</PaymentTermsOfSale>
</PaymentTerms>
</OrderCreateProperties>
<OrderCreatePartners>
<Buyer>
<PartnerInformation>
<PartnerName>MOSLLC</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0089646370000</PartnerIdentifier>
<ContactInformation>
<ContactName>MOSLLC LLC</ContactName>
<ContactNumber>804-281-1402</ContactNumber>
<EmailAddress>Jim.Paul#sscoop.com</EmailAddress>
</ContactInformation>
</PartnerInformation>
</Buyer>
<Seller>
<PartnerInformation>
<PartnerName>WalmartPartnerName</PartnerName
<PartnerIdentifier Agency="IBM-EBID">0062668030000</PartnerIdentifier>
</PartnerInformation>
</Seller>
<ShipTo>
<PartnerInformation>
<PartnerName>ORANGE MADISON COOP ORANGE BR</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0238626420000</PartnerIdentifier>
<AddressInformation>
<AddressLine>13323 JAMES MADISON HWY</AddressLine>
<CityName>ORANGE</CityName>
<StateOrProvince>VA</StateOrProvince>
<PostalCode>22960</PostalCode>
<PostalCountry>US</PostalCountry>
</AddressInformation>
</PartnerInformation>
</ShipTo>
<Payer>
<PartnerInformation>
<PartnerName>MOSLLC</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0089646370000</PartnerIdentifier>
</PartnerInformation>
</Payer>
</OrderCreatePartners>
<OrderCreateDetails>
<OrderCreateProductLineItem>
<LineNumber>1</LineNumber>
<PurchaseOrderLineItemNumber>1</PurchaseOrderLineItemNumber>
<ProductIdentification>
<ProductIdentifier Agency="AssignedByManufacturer">883580921503</ProductIdentifier>
<ProductName>HARNESS XTRA 5.6L RUP BULK</ProductName>
<ProductDescription>HARNESS XTRA 5.6L RUP BULK</ProductDescription>
</ProductIdentification>
<ProductQuantity>
<Measurement>
<MeasurementValue>1000</MeasurementValue>
<UnitOfMeasureCode Domain="UN-Rec-20">GLL</UnitOfMeasureCode>
</Measurement>
</ProductQuantity>
<ScheduleDateTimeInformation ScheduleType="RequestedDelivery">
<DateTimeInformation>
<DateTime DateTimeQualifier="On">2014-08-22T00:00:00Z</DateTime>
</DateTimeInformation>
</ScheduleDateTimeInformation>
</OrderCreateProductLineItem>
</OrderCreateDetails>
</OrderCreateBody>
</OrderCreate>
</soapenv:Body>
Expected output:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<OrderCreate Version="2.0.2">
<Header xmlns="urn:midx:names:specification:ces:schema:all:5:1:1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ThisDocumentIdentifier>
<DocumentIdentifier>58585993</DocumentIdentifier>
</ThisDocumentIdentifier>
<ThisDocumentDateTime>
<DateTime xmlns="" DateTimeQualifier="On">20140822000000</DateTime>
</ThisDocumentDateTime>
<From>
<PartnerInformation>
<PartnerName>MOSLLC</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0089646370000</PartnerIdentifier>
<ContactInformation>
<ContactName>MOSLLC </ContactName>
<ContactName>804-281-1402</ContactName>
<EmailAddress/>
</ContactInformation>
</PartnerInformation>
</From>
<To>
<PartnerInformation>
<PartnerName>Walmart</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0062668030000</PartnerIdentifier>
</PartnerInformation>
</To>
</Header>
<OrderCreateBody xmlns="urn:midx:names:specification:ces:schema:all:5:1:1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OrderCreateProperties>
<PurchaseOrderNumber>
<DocumentIdentifier>OD3157538</DocumentIdentifier>
</PurchaseOrderNumber>
<PurchaseOrderTypeCode Domain="ANSI ASC X12 92">KN</PurchaseOrderTypeCode>
<PurchaseOrderIssuedDate>
<DateTime xmlns="" DateTimeQualifier="On">20140822000000</DateTime>
</PurchaseOrderIssuedDate>
<LanguageCode Domain="ISO 639-2/T">eng</LanguageCode>
<CurrencyCode Domain="ISO 4217">USD</CurrencyCode>
<BuyerSequenceNumber>0</BuyerSequenceNumber>
<DeliveryTerms>
<DeliveryTermsCode Domain="Incoterms-2000">CPT</DeliveryTermsCode>
<DeliveryTermsLocation>ORIGIN</DeliveryTermsLocation>
</DeliveryTerms>
<ShipmentMethodOfPaymentCode Domain="ANSI-ASC-X12-146">PC</ShipmentMethodOfPaymentCode>
<PaymentTerms>
<PaymentTermsOfSale>
<TermsOfSaleDescription>DUE 25TH OF FOLLOWING MONTH</TermsOfSaleDescription>
<NetDaysDue>0</NetDaysDue>
</PaymentTermsOfSale>
</PaymentTerms>
</OrderCreateProperties>
<OrderCreatePartners>
<Buyer>
<PartnerInformation>
<PartnerName>MOSLLC</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0089646370000</PartnerIdentifier>
<ContactInformation>
<ContactName>MOSLLC LLC</ContactName>
<TelephoneNumber>
<NationalPhoneNumber>813-217-9512</NationalPhoneNumber>
</TelephoneNumber>
<ContactNumber>804-281-1402</ContactNumber>
<EmailAddress>Jim.Paul#sscoop.com</EmailAddress>
</ContactInformation>
</PartnerInformation>
</Buyer>
<Seller>
<PartnerInformation>
<PartnerName>WalmartPartnerName</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0062668030000</PartnerIdentifier>
</PartnerInformation>
</Seller>
<ShipTo>
<PartnerInformation>
<PartnerName>ORANGE MADISON COOP ORANGE BR</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0238626420000</PartnerIdentifier>
<AddressInformation>
<AddressLine>13323 JAMES MADISON HWY</AddressLine>
<CityName>ORANGE</CityName>
<StateOrProvince>VA</StateOrProvince>
<PostalCode>22960</PostalCode>
<PostalCountry>US</PostalCountry>
</AddressInformation>
</PartnerInformation>
</ShipTo>
<Payer>
<PartnerInformation>
<PartnerName>MOSLLC</PartnerName>
<PartnerIdentifier Agency="IBM-EBID">0089646370000</PartnerIdentifier>
</PartnerInformation>
</Payer>
</OrderCreatePartners>
<OrderCreateDetails>
<OrderCreateProductLineItem>
<LineNumber>1</LineNumber>
<PurchaseOrderLineItemNumber>1</PurchaseOrderLineItemNumber>
<ProductIdentification>
<ProductIdentifier Agency="AssignedByManufacturer">883580921503</ProductIdentifier>
<ProductName>HARNESS XTRA 5.6L RUP BULK</ProductName>
<ProductDescription>HARNESS XTRA 5.6L RUP BULK</ProductDescription>
</ProductIdentification>
<ProductQuantity>
<Measurement>
<MeasurementValue>1000</MeasurementValue>
<UnitOfMeasureCode Domain="UN-Rec-20">GLL</UnitOfMeasureCode>
</Measurement>
</ProductQuantity>
<ScheduleDateTimeInformation ScheduleType="RequestedDelivery">
<DateTimeInformation>
<DateTime xmlns="" DateTimeQualifier="On">20140822000000</DateTime>
</DateTimeInformation>
</ScheduleDateTimeInformation>
</OrderCreateProductLineItem>
</OrderCreateDetails>
</OrderCreateBody>
</OrderCreate>
</soapenv:Body>
This is the part which needs to be added
After element Buyer/ContactDescription I need add this
<TelephoneNumber>
<NationalPhoneNumber>605225-1372</NationalPhoneNumber>
</TelephoneNumber>
This is the sample code I wrote. Can anyone please guide me?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" extension-element-prefixes="dp">
<xsl:output method="xml"/>
<xsl:template match="attribute::Domain[starts-with(name(..),'PurchaseOrderType')]">
<xsl:attribute name="Domain"><xsl:value-of select="translate(., '-', ' ')"/></xsl:attribute>
</xsl:template>
<xsl:template match="attribute::*">
<xsl:copy/>
</xsl:template>
<xsl:template match="attribute::Domain[starts-with(name(..),'CurrencyCode')]">
<xsl:attribute name="Domain"><xsl:value-of select="translate(., '-', ' ')"/></xsl:attribute>
</xsl:template>
<xsl:template match="attribute::*">
<xsl:copy/>
</xsl:template>
<!-- <xsl:template match="attribute::Domain[starts-with(name(..),'LanguageCode')]">
<xsl:attribute name="Domain"><xsl:value-of select="translate('.', '-', ' ')"/>
</xsl:attribute>
</xsl:template>
-->
<xsl:template match="attribute::Domain[starts-with(name(..),'LanguageCode')]">
<xsl:attribute name="Domain"><xsl:value-of select="concat('ISO ',substring-after(substring-before(.,'T'),'-'), '/T')"/></xsl:attribute>
</xsl:template>
<xsl:template match="attribute::*">
<xsl:copy/>
</xsl:template>
<xsl:template match="*[local-name()='DateTime']">
<DateTime>
<xsl:copy-of select="attribute::*"/>
<xsl:value-of select="translate(., '-T:Z', '')"/>
</DateTime>
</xsl:template>
<xsl:template match="*[local-name()='OrderCreate']">
<OrderCreate Version="2.0.2">
<xsl:apply-templates select="node()"/>
</OrderCreate>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="attribute::*|node()"/>
</xsl:element>
<!--Adding the elements
<TelephoneNumber>
<NationalPhoneNumber>605225-1372</NationalPhoneNumber>
</TelephoneNumber>-->
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="attribute::*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Buyer/ContactName">
<xsl:copy-of select="."/>
<xsl:element name="TelephoneNumber">
<xsl:attribute name="NationalPhoneNumber">605225-1372</xsl:attribute>
</xsl:element>
<!--<TelephoneNumber>
<NationalPhoneNumber>605225-1372</NationalPhoneNumber>
</TelephoneNumber>-->
</xsl:template>
</xsl:stylesheet>

To fix your issue you need two changes:
Specify the default namespace of your document in the root tag using some prefix, e.g. "my":
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="urn:midx:names:specification:ces:schema:all:5:1:1"
xmlns:dp="http://www.datapower.com/extensions" extension-element-prefixes="dp">
Fix your Buyer template:
<xsl:template match="my:Buyer/my:PartnerInformation/my:ContactInformation/my:ContactName">
<xsl:copy-of select="."/>
<TelephoneNumber xmlns="urn:midx:names:specification:ces:schema:all:5:1:1">
<NationalPhoneNumber>605225-1372</NationalPhoneNumber>
</TelephoneNumber>
</xsl:template>

Thank you Lagivan and Mathias. Can you please explain the use of adding the namespace?
The answer is too long to be added in a comment, that is why I write a separate answer, even though #lagivan has already given an answer in terms of code.
The reason why adding the namespace solves your problem is that elements with a namespace are different from ones without a namespace, even if their element names are the same. Or put in another way,
<ns:number xmlns:ns="www.ns.com"/>
is entirely different from
<number>
ns:number is said to be prefixed, which is shorthand for saying it belongs to a certain namespace, in this case www.ns.com. Besides, there is a way to define a default namespace:
<number xmlns="www.ns.com">
<digit/>
</number>
In the example above, there is a default namespace defined on the number element. This does not have any effect for the number element itself, but all descendants of number (in this case only digit) will take on this namespace.
Now, turning to your specific problem, the element you'd like to match (ContactName) is not itself prefixed, but it has a default namespace. This default namespace is not declared on the ContactName element, but higher up in the tree, on the OrderCreate element:
<OrderCreate Version="5.1.1" xmlns="urn:midx:names:specification:ces:schema:all:5:1:1">
Any descendant of OrderCreate will be in the namespace urn:midx:names:specification:ces:schema:all:5:1:1, for example ... ContactName.
What this means for your XSLT code is that if you want to match the ContactName element from the input, you must declare this namespace in your XSLT stylesheet and prefix the element name to be able to find it.
<xsl:stylesheet xmlns:my="urn:midx:names:specification:ces:schema:all:5:1:1">
Now you can write templates to match the descendant elements of OrderCreate, always prefixing them with my::
<xsl:template match="my:ContactName">
On the other hand,
<xsl:template match="ContactName">
will never match anything because such an element (one that is called "ContactName" and one that is not in any namespace) does not exist in your input XML.

Related

XSLT 3 multi-step transformation

Building from the transformation in this post, I'm now trying to integrate it into a two step transformation where the same node is transformed twice. Tested independent of each other, the transformations work. For reasons I don't understand, when I bring them together using modes, it's not going through the steps correctly - somehow the modes and variables are not aligned correctly? Fiddle here.
Given this XML:
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:id="MS609-1577">
<teiHeader/>
<text>
<body>
<ab xml:id="MS609-1577-LA" xml:lang="la">
<seg type="dep_event" subtype="sighting" xml:id="MS609-1214-1"><pb break="y" n="80r"/><lb break="y" n="1"/>Item. <date type="deposition_date" when="1245-07-11" xml:id="MS609-1214_depdate">Anno Domini M°CC°XL°V° II° Ydus Junii</date>.
<persName ref="#peire_de_saint-michel" role="dep">P<supplied reason="abbr-name">etrus</supplied> de Sancto Michaele, miles</persName>, testis juratus dixit quod vidit apud
<placeName ref="#laurac_aude" type="sighting_loc">Laurac
<persName ref="#heretics_in_public" role="her">hereticos</persName><lb break="y" n="2"/>publice manentes</placeName>
set nullam familiari<del type="expunctus" rend="after">a</del>tatem habuit cum eis. <date type="sighting_date" when="1225" datingPoint="#MS609-1214_depdate" unit="y" interval="-20">Et sunt XX anni vel circa</date>.</seg>
</ab>
</body>
</text>
</TEI>
My objective is to transform this fragment:
<date type="deposition_date" when="1245-07-11" xml:id="MS609-1214_depdate">Anno Domini M°CC°XL°V° II° Ydus Junii</date>.
Into this ('moving' some text and applying analyze-string to the same node) :
<date type="deposition_date" when="1245-07-11" xml:id="MS609-1214_depdate">Anno Domini M<hi rend="sup">o</hi>CC<hi rend="sup">o</hi>XL<hi rend="sup">o</hi>V<hi rend="sup">o</hi> II<hi rend="sup">o</hi> Ydus Junii.</date>
And the rest copy without changes.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tei="http://www.tei-c.org/ns/1.0"
exclude-result-prefixes="tei"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
<xsl:variable name="step-one-result">
<xsl:apply-templates select="/" mode="step1"/>
</xsl:variable>
<xsl:apply-templates select="$step-one-result" mode="step2"/>
</xsl:template>
<xsl:template match="text()[contains(.,'°')]" mode="step1">
<xsl:analyze-string select="." regex="°">
<xsl:matching-substring>
<hi xmlns="http://www.tei-c.org/ns/1.0" rend="sup">o</hi>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="tei:date[#type='deposition_date' and ./following-sibling::node()[1][. instance of text() and starts-with(.,'.')]]" mode="step2">
<date xmlns="http://www.tei-c.org/ns/1.0">
<xsl:copy-of select="./#*"/>
<xsl:copy-of select="./(* | text())"/>
<xsl:text>.</xsl:text>
</date>
</xsl:template>
<xsl:template match="text()[preceding-sibling::node()[1][./self::tei:date[#type='deposition_date']]][starts-with(.,'.')]" mode="step2">
<xsl:value-of select="substring(.,2)"/>
</xsl:template>
</xsl:stylesheet>
Many thanks in advance.
As you are pushing the whole tree through your modes, I think you forgot to declare
<xsl:mode name="step1" on-no-match="shallow-copy"/>
<xsl:mode name="step2" on-no-match="shallow-copy"/>

Troubleshooting XSLT namespace issue

I am trying to use XSLT to transform an XML document into a very similar XML document, but with a couple of additions. I'm having trouble getting xsl:copy-of to work properly. When I try to transform the following sample XML document:
<?xml version="1.0" encoding="UTF-8"?>
<mods xmlns="http://www.loc.gov/mods/v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:mods="http://www.loc.gov/mods/v3"
xsi:schemaLocation="http://www.loc.gov/mods/v3
http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
<titleInfo>
<title>Test title
</title>
</titleInfo>
<subject authority="naf">
<geographic>Geo subject</geographic>
</subject>
<location>
<physicalLocation>Location here</physicalLocation>
</location>
<originInfo>
<dateCreated keyDate="yes">1904-01-05</dateCreated><dateCreated/>
</originInfo>
<typeOfResource>text</typeOfResource>
<genre authority="aat" valueURI="300026880">correspondence</genre>
<physicalDescription>
<extent>3 pages.</extent>
<note type="physical description">All pages ripped down the
middle.
</note>
</physicalDescription>
<relatedItem type="host" displayLabel="Collection"
<titleInfo>
<title>Collection name</title>
</titleInfo>
</relatedItem>
<accessCondition type="use and reproduction" displayLabel="Use and
Reproduction">Access condition here</accessCondition>
<identifier type="local">IDID</identifier>
</mods>
Using the following XSLT, only the literal values in the XSLT (originInfo, accessCondition) are output in the result XML document. I can't figure out why this is. When I remove all the header info from the source XML, the transform DOES work. But all my XML files have that header, and I want to make the XSLT work with it in - my guess is that my namespace declarations are contradicting each other, but I can't figure out why.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xlink="https://www.w3.org/1999/xlink"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mods="http://www.loc.gov/mods/v3" version="2.0" exclude-
result-prefixes="mods">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<mods>
<xsl:copy-of select="mods/titleInfo"/>
<xsl:copy-of select="mods/typeOfResource"/>
<xsl:copy-of select="mods/location"/>
<xsl:copy-of select="mods/physicalDescription"/>
<xsl:copy-of select="mods/subject"/>
<xsl:copy-of select="mods/name"/>
<xsl:copy-of select="mods/identifier"/>
<xsl:copy-of select="mods/genre"/>
<xsl:copy-of select="mods/relatedItem"/>
<xsl:copy-of select="mods/accessCondition"/>
<xsl:copy-of select="mods/language"/>
<xsl:copy-of select="mods/abstract"/>
<xsl:copy-of select="mods/note"/>
<originInfo>
<dateCreated>
<xsl:value-of select="mods/originInfo/dateCreated"/>
</dateCreated>
<dateCreated encoding="w3cdtf" keyDate="yes"
point="start">
<xsl:value-of select="mods/originInfo/dateCreated"/>
</dateCreated>
</originInfo>
<accessCondition type="use and reproduction">
<xsl:text>Copyright statement here</xsl:text>
</accessCondition>
</mods>
</xsl:template>
My expected output is:
<?xml version="1.0" encoding="UTF-8"?>
<mods xmlns="http://www.loc.gov/mods/v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:mods="http://www.loc.gov/mods/v3"
xsi:schemaLocation="http://www.loc.gov/mods/v3
http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
<titleInfo>
<title>Test title
</title>
</titleInfo>
<subject authority="naf">
<geographic>Geo subject</geographic>
</subject>
<location>
<physicalLocation>Location here</physicalLocation>
</location>
<typeOfResource>text</typeOfResource>
<genre authority="aat" valueURI="300026880">correspondence</genre>
<physicalDescription>
<extent>3 pages.</extent>
<note type="physical description">All pages ripped down the
middle.
</note>
</physicalDescription>
<relatedItem type="host" displayLabel="Collection"
<titleInfo>
<title>Collection name</title>
</titleInfo>
</relatedItem>
<accessCondition type="use and reproduction" displayLabel="Use and
Reproduction">Access condition here</accessCondition>
<identifier type="local">IDID</identifier>
<originInfo>
<dateCreated>1904-01-05 </dateCreated>
<dateCreated encoding="w3cdtf" keyDate="yes" point="start">1904-01-05 </dateCreated>
</originInfo>
<accessCondition type="use and reproduction">Copyright statement here</accessCondition>
</mods>
There are two problems with your XSLT:
It does not select anything in the XML input, because your XML input puts its nodes in a namespace. If you're using XSLT 2.0, you can solve this by including xpath-default-namespace="http://www.loc.gov/mods/v3" in your xsl:stylesheet opening tag.
It does not put the literal result elements in the target namespace. In order to do this, you must declare the target namespace as the default namespace in one of the higher-level nodes, e.g. by including xmlns="http://www.loc.gov/mods/v3" in your xsl:stylesheet opening tag.
In addition, in order to prevent the original namespace declarations being replicated to every element copied by your stylesheet, you would do well to replace the literal result element <mods> by a copy of the original one.
Here's a complete stylesheet incorporating these changes:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.loc.gov/mods/v3"
xpath-default-namespace="http://www.loc.gov/mods/v3">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/mods">
<xsl:copy>
<xsl:copy-of select="titleInfo"/>
<xsl:copy-of select="typeOfResource"/>
<xsl:copy-of select="location"/>
<xsl:copy-of select="physicalDescription"/>
<xsl:copy-of select="subject"/>
<xsl:copy-of select="name"/>
<xsl:copy-of select="identifier"/>
<xsl:copy-of select="genre"/>
<xsl:copy-of select="relatedItem"/>
<xsl:copy-of select="accessCondition"/>
<xsl:copy-of select="language"/>
<xsl:copy-of select="abstract"/>
<xsl:copy-of select="note"/>
<originInfo>
<dateCreated>
<xsl:value-of select="originInfo/dateCreated"/>
</dateCreated>
<dateCreated encoding="w3cdtf" keyDate="yes" point="start">
<xsl:value-of select="originInfo/dateCreated"/>
</dateCreated>
</originInfo>
<accessCondition type="use and reproduction">
<xsl:text>Copyright statement here</xsl:text>
</accessCondition>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Demo: http://xsltransform.hikmatu.com/gWmuiHV

Multiple transformations to an xml file using xslt 1

Newbie to this site and using xslt but running into a roadblock transforming a SSRS 2008v2 rendered xml file into another XSL raw format for a 3rd Party EDI transfer. I've been searching this site and others for a while now, but struggling putting it all together.I'm starting with the following raw xml data;
<Invoices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.spscommerce.com/RSX" xsi:schemaLocation="http://www.spscommerce.com/RSX http://tfl- sql01/ReportServer_SQL2012? %2FTesting%2FINTest&rs%3ACommand=Render&rs%3AFormat=XML&rs%3ASessionID= jn5ugdirg4m02nmodnm0hynq&rc%3ASchema=True" Name="INTest">
<Invoices1> ***need to remove***
<ivhID_Collection> ***need to remove***
<Invoices>...</Invoices>
<Invoices>...</Invoices>
<Invoices>
<Invoice>
<Header1>
<InvoiceHeader>...</InvoiceHeader>
<PaymentTerms>...</PaymentTerms>
<Dates>...</Dates>
<Address>...</Address>
<References>...</References>
<ChargesAllowances>...</ChargesAllowances>
<LineItem_Collection> ***need to remove and replace with </Header>***
<LineItem>
<InvoiceLine>...</InvoiceLine>
<ProductOrItemDescription>...</ProductOrItemDescription>
</LineItem>
<LineItem>
<InvoiceLine>...</InvoiceLine>
<ProductOrItemDescription>...</ProductOrItemDescription>
</LineItem>
</LineItem_Collection> ***need to remove***
<Summary>...</Summary>
</Header1> ***need to remove***
</Invoice>
</Invoices>
<Invoices>...</Invoices>
<Invoices>...</Invoices>
<Invoices>...</Invoices>
/ivhID_Collection> ***need to remove***
</Invoices1> ***need to remove***
</Invoices>
Trying to get it in this structure instead;
<Invoices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.spscommerce.com/RSX" xsi:schemaLocation="http://www.spscommerce.com/RSX http://tfl-sql01/ReportServer_SQL2012?%2FTesting%2FINDoItBest%20v7&rs%3ACommand=Render&rs%3AFormat=XML&rs%3ASessionID=jn5ugdirg4m02nmodnm0hynq&rc%3ASchema=True" Name="INDoItBest v7">
<Invoices>...</Invoices>
<Invoices>...</Invoices>
<Invoices>
<Invoice>
<Header>
<InvoiceHeader>...</InvoiceHeader>
<PaymentTerms>...</PaymentTerms>
<Dates>...</Dates>
<Address>...</Address>
<References>...</References>
<ChargesAllowances>...</ChargesAllowances>
</Header>
<LineItem>
<InvoiceLine>...</InvoiceLine>
<ProductOrItemDescription>...</ProductOrItemDescription>
</LineItem>
<LineItem>
<InvoiceLine>...</InvoiceLine>
<ProductOrItemDescription>...</ProductOrItemDescription>
</LineItem>
<Summary>...</Summary>
</Invoice>
</Invoices>
<Invoices>...</Invoices>
<Invoices>...</Invoices>
<Invoices>...</Invoices>
</Invoices>
I made some progress using this style sheet, but am stuck on the regrouping of the Header tag and the display of the element namespace.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:t="http://www.spscommerce.com/RSX"
exclude-result-prefixes="t">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<!--rule to suppress the undesired nodes-->
<xsl:template match="t:Invoices1|t:ivhID_Collection">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="t:LineItem_Collection">
<xsl:apply-templates/>
</xsl:template>
<!--<xsl:template match="t:Invoice/t:Header1">
<xsl:apply-templates/>
</xsl:template>-->
<!-- Identity Transform -->
<xsl:template match="t:Header1">
<xsl:copy>
<xsl:element name="Header">
<xsl:apply-templates select="#*|t:InvoiceHeader|t:PaymentTerms|t:Dates|t:Address|t:References|t:ChargesAllowances"/>
</xsl:element>
<xsl:apply-templates select="#*|t:LineItem_Collection|t:Summary"/>
</xsl:copy>
</xsl:template>
<!-- Had to comment out -->
<!--<xsl:template match="t:Invoice/t:Header1">
<xsl:apply-templates/>
</xsl:template>-->
The stylesheet produced most of what I needed, but failed when I tried to remove the Header1 tag (code commented out). Also, struggling to understand why "exclude-result-prefixes" isn't working to remove the namespace from the new xml file.
<Invoices xmlns="http://www.spscommerce.com/RSX" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.spscommerce.com/RSX http://tfl-sql01/ReportServer_SQL2012?%2FTesting%2FINDoItBest%20v7&rs%3ACommand=Render&rs%3AFormat=XML&rs%3ASessionID=jn5ugdirg4m02nmodnm0hynq&rc%3ASchema=True" Name="INDoItBest v7">
<Invoices>...</Invoices>
<Invoices>...</Invoices>
<Invoices>
<Invoice>
<Header1>
<Header xmlns="">
<InvoiceHeader xmlns="http://www.spscommerce.com/RSX">... </InvoiceHeader>
<PaymentTerms xmlns="http://www.spscommerce.com/RSX">... </PaymentTerms>
<Dates xmlns="http://www.spscommerce.com/RSX">...</Dates>
<Address xmlns="http://www.spscommerce.com/RSX">...</Address>
<References xmlns="http://www.spscommerce.com/RSX">...</References>
<ChargesAllowances xmlns="http://www.spscommerce.com/RSX">... </ChargesAllowances>
</Header>
<LineItem>
<InvoiceLine>...</InvoiceLine>
<ProductOrItemDescription>...</ProductOrItemDescription>
</LineItem>
<LineItem>
<InvoiceLine>...</InvoiceLine>
<ProductOrItemDescription>...</ProductOrItemDescription>
</LineItem>
<Summary>
<TotalAmount>756.8400</TotalAmount>
<TotalSalesAmount>727.1600</TotalSalesAmount>
<TotalLineItemNumber>2</TotalLineItemNumber>
</Summary>
</Header1>
</Invoice>
</Invoices>
<Invoices>...</Invoices>
<Invoices>...</Invoices>
<Invoices>...</Invoices>
</Invoices>
Any advice or other options would be greatly appreciated!
You've already got a template matching t:Header1 in your XSLT, so you shouldn't add another one matching it, as only one can apply. (In your case, if you did add a template matching t:Invoice\t:Header1 then because of the parent being specified, it would have a higher priority as the one just matching t:Header1 and be used instead).
What you will need to do, is put all the logic in the single template. In this case, all you need to do is remove the xsl:copy from that template to avoid the Header1 being copied to the output tree. Additionally, when you create Header, you are creating it in no namespace, not in the namespace bound to the prefix "t". Therefore, the child elements will be given new namespace declarations because they will still be in that namespace.
One way to do it is simply add a "namespace" attribute to the xsl:element, like so:
<xsl:element name="Header" namespace="http://www.spscommerce.com/RSX">
Alternatively, you can create the element by just doing <Header> but you will need to add a default namespace declaration to the XSLT too, to ensure it gets output in the correct namespace.
Try this XSLT:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:t="http://www.spscommerce.com/RSX"
xmlns="http://www.spscommerce.com/RSX"
exclude-result-prefixes="t">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<!--rule to suppress the undesired nodes-->
<xsl:template match="t:Invoices1|t:ivhID_Collection">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="t:LineItem_Collection">
<xsl:apply-templates/>
</xsl:template>
<!-- Identity Transform -->
<xsl:template match="t:Header1">
<xsl:apply-templates select="#*" />
<Header>
<xsl:apply-templates select="#*|t:InvoiceHeader|t:PaymentTerms|t:Dates|t:Address|t:References|t:ChargesAllowances"/>
</Header>
<xsl:apply-templates select="t:LineItem_Collection|t:Summary"/>
</xsl:template>
</xsl:stylesheet>
As a side note, in your XSLT you were also doing this immediately after creating the Header element
<xsl:apply-templates select="#*|t:LineItem_Collection|t:Summary"/>
This would fail if the Header1 had attributes you wanted to copy, as it is an error to try to add attributes to a parent element after you have created child elements. This is why in my XSLT I have split the statement into two.

XSLT To Bring Child Elements into Parent As Attributes And Keep Existing Parent Attribute

I'm stumped and am very new to XSLT. A little direciton would be greatly appreciated. My ultimate objective is to bring the firstName, lastName, and gender elements under the student element up into that element as attributes, but also want to retain the StudentID attribute that already exists there. I'd also like that "year_Collection" to disappear.
I started with this XML document
<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="Upload" Name="Upload">
<student StudentID="123456">
<firstName firstName="John"/>
<lastName lastName="Johnson"/>
<gender gender="M"/>
<year_Collection>
<year value="2013">
<term hoursEarned="18.00" hoursAttempted="18.00" termCode="S1"/>
</year>
</year_Collection>
</student>
</Report>
My desired output looks like this
<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="Upload" Name="Upload">
<student gender="M" lastName="Johnson" firstName="John" StudentID="123456">
<year value="2013">
<term hoursEarned="18.00" hoursAttempted="18.00" termCode="S1"/>
</year>
</student>
</Report>
I was able to use this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:r="Upload" exclude-result-prefixes="r" extension-element-prefixes="r">
<xsl:template match="r:student">
<xsl:copy>
<xsl:for-each select="*">
<xsl:attribute name="{local-name(.)}">
<xsl:value-of select="."/>
</xsl:attribute>
<xsl:copy-of select="#*"/>
<xsl:apply-templates/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
To get here:
<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="Upload" Name="Upload">
<student year_Collection="" gender="M" lastName="Johnson" firstName="John">
<year value="2013">
<term hoursEarned="18.00" hoursAttempted="18.00" termCode="S1"/>
</year>
</student>
</Report>
But it overwrites the StudentID attribute that already exists. How do I get the elements to come up as attributes, but not overwrite StudentID?
Also, that pesky year_collection element won't disappear with this, but I can split that into a separate question if that's a better way to go about it.
<xsl:template match="r:year_Collection">
<xsl:apply-templates/>
</xsl:template>
But it overwrites the StudentID attribute that already exists.
No, it doesn't. The problem is you're not copying it. You should start your template with:
<xsl:template match="r:student">
<xsl:copy>
<xsl:copy-of select="#StudentID"/>
or, if you prefer:
<xsl:template match="r:student">
<xsl:copy>
<xsl:copy-of select="#*"/>
to copy any and all attributes the Student has.
Regarding the problem with<year_Collection>, you should try to turn only leaf nodes into attributes, for example:
<xsl:template match="r:student">
<xsl:copy>
<xsl:copy-of select="#*"/>
<xsl:copy-of select="*/#*"/>
<xsl:copy-of select="*/*[#*]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Of course, if your structure is known, naming the required nodes explicitly would be much better, e.g;
<xsl:template match="r:student">
<xsl:copy>
<xsl:copy-of select="#StudentID | r:firstName/#firstName | r:lastName/#lastName | r:gender/#gender"/>
<xsl:copy-of select="r:year_Collection/r:year"/>
</xsl:copy>
</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>