Adding multiple namespaces to a xml file
I have a xml file and namespaces are given in the xml file. What I need to do is to use the namespaces given in the xml file only and qualify the xml file. Below is the sample xml file.
<Ticketing xmlns="ticketing.4.0" mfAction="BOOKING">
<Reference>
<Code>190</Code>
</Reference>
<BookingID>194283532</BookingID>
<BookingCode>MCHOI190</BookingCode>
<BookingDate>2011-04-21T15:40:04.000</BookingDate>
<Persons>
<Person>
<Code>ADULT</Code>
<Count>2</Count>
</Person>
<Person>
<Code>CHILD</Code>
<Count>2</Count>
</Person>
</Persons>
<CreditCards>
<CreditCard BookingType="BOOKING">
<BookCredit开发者_开发知识库Card xmlns="creditcard.3.0">
<CardCode>VS</CardCode>
<CardNumber>4444333322221111</CardNumber>
<CardExpire>2011-12-31</CardExpire>
</BookCreditCard>
</CreditCard>
</CreditCards>
</Ticketing>
I have to use the namespaces already present in the xml file and give them a prefix and qualify the xml with those namespaces. The output should be like below:-
<ticket:Ticketing xmlns:ticket="ticketing.4.0" mfAction="BOOKING">
<ticket:Reference>
<ticket:Code>190</ticket:Code>
</ticket:Reference>
<ticket:BookingID>194283532</ticket:BookingID>
<ticket:BookingCode>MCHOI190</ticket:BookingCode>
<ticket:BookingDate>2011-04-21T15:40:04.000</ticket:BookingDate>
<ticket:Persons>
<ticket:Person>
<ticket:Code>ADULT</ticket:Code>
<ticket:Count>2</ticket:Count>
</ticket:Person>
<ticket:Person>
<ticket:Code>CHILD</ticket:Code>
<ticket:Count>2</ticket:Count>
</ticket:Person>
</ticket:Persons>
<ticket:CreditCards>
<ticket:CreditCard BookingType="BOOKING">
<credit:BookCreditCard xmlns:credit="creditcard.3.0">
<credit:CardCode>VS</credit:CardCode>
<credit:CardNumber>4444333322221111</credit:CardNumber>
<credit:CardExpire>2011-12-31</credit:CardExpire>
</credit:BookCreditCard>
</ticket:CreditCard>
</ticket:CreditCards>
</ticket:Ticketing>
Can someone suggest how to implement this. Thanks Rudra
I'm not sure is the best way to do it. But it does the job:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="*">
<xsl:element name="ticket:{name()}" namespace="ticketing.4.0">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="BookCreditCard|BookCreditCard//*"">
<xsl:element name="credit:{name()}" namespace="creditcard.3.0">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
In XSLT 1.0 there is no guaranteed solution, because implementations are free to use any prefix in the output file that they want. However most processors do the reasonable thing, and @empo's solution will therefore usually work. In XSLT 2.0 it is guaranteed to work.
I would be inclined to use the namespace to control which template is chosen, something like this:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ticket="ticketing.4.0" xmlns:credit="creaditcard.3.0">
<xsl:output indent="yes"/>
<xsl:template match="ticket:*">
<xsl:element name="ticket:{local-name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="credit:*">
<xsl:element name="credit:{local-name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
A more general solution (no hardcoded prefixes and can work with any number of namespaces):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="*">
<xsl:element name=
"{substring(namespace-uri(),1,6)}:{local-name()}"
namespace="{namespace-uri()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<Ticketing xmlns="ticketing.4.0" mfAction="BOOKING">
<Reference>
<Code>190</Code>
</Reference>
<BookingID>194283532</BookingID>
<BookingCode>MCHOI190</BookingCode>
<BookingDate>2011-04-21T15:40:04.000</BookingDate>
<Persons>
<Person>
<Code>ADULT</Code>
<Count>2</Count>
</Person>
<Person>
<Code>CHILD</Code>
<Count>2</Count>
</Person>
</Persons>
<CreditCards>
<CreditCard BookingType="BOOKING">
<BookCreditCard xmlns="creditcard.3.0">
<CardCode>VS</CardCode>
<CardNumber>4444333322221111</CardNumber>
<CardExpire>2011-12-31</CardExpire>
</BookCreditCard>
</CreditCard>
</CreditCards>
</Ticketing>
the wanted, correct result is produced:
<ticket:Ticketing xmlns:ticket="ticketing.4.0" mfAction="BOOKING">
<ticket:Reference>
<ticket:Code>190</ticket:Code>
</ticket:Reference>
<ticket:BookingID>194283532</ticket:BookingID>
<ticket:BookingCode>MCHOI190</ticket:BookingCode>
<ticket:BookingDate>2011-04-21T15:40:04.000</ticket:BookingDate>
<ticket:Persons>
<ticket:Person>
<ticket:Code>ADULT</ticket:Code>
<ticket:Count>2</ticket:Count>
</ticket:Person>
<ticket:Person>
<ticket:Code>CHILD</ticket:Code>
<ticket:Count>2</ticket:Count>
</ticket:Person>
</ticket:Persons>
<ticket:CreditCards>
<ticket:CreditCard BookingType="BOOKING">
<credit:BookCreditCard xmlns:credit="creditcard.3.0">
<credit:CardCode>VS</credit:CardCode>
<credit:CardNumber>4444333322221111</credit:CardNumber>
<credit:CardExpire>2011-12-31</credit:CardExpire>
</credit:BookCreditCard>
</ticket:CreditCard>
</ticket:CreditCards>
</ticket:Ticketing>
Do note: The first 6 characters of the namespace-uri of each element are used for the prefix of the corresponding generated name. Therefore this solution works correctly as long as the starting 6 characters of any namespace-uri of an element obey the sintactical rules for NCName.
精彩评论