开发者

Adding multiple namespaces to a xml file

开发者 https://www.devze.com 2023-03-05 14:00 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号