开发者

Transform XML using XSLT

I want to transform the XML using XSLT Here is my sample XML

<EmployeList>
  <EMpDetails>
    <Name>Kiran</Name>
    <ID>ID001</ID>
    <city>Hyderabad</city>
    <Country>India</Country>
  </EMpDetails&开发者_运维技巧gt;
  <EMpDetails>
    <Name>Sunny</Name>
    <ID>ID002</ID>
    <city>Banglore</city>
    <Country>INDIA</Country>
  </EMpDetails>
  <EMpDetails>
    <Name>John</Name>
    <ID>ID001</ID>
    <city>TEXAS</city>
    <Country>US</Country>
  </EMpDetails>
  <EMpDetails>
    <Name>Raj</Name>
    <ID>ID006</ID>
    <city>Dallas</city>
    <Country>US</Country>
  </EMpDetails>
  <EMpDetails>
    <Name>Nag</Name>
    <ID>ID007</ID>
    <city>ITALY</city>
    <Country>Rome</Country>
  </EMpDetails>
</EmployeList>

Required output using XSLT

<EmployeList>
  <EMpDetails>
    <Name>Kiran</Name>
    <ID>ID001</ID>
    <city>Hyderabad</city>
    <Country>India</Country>
  </EMpDetails>
  <EMpDetails>
    <Name>Sunny</Name>
    <ID>ID002</ID>
    <city>Banglore</city>
    <Country>INDIA</Country>
  </EMpDetails>   
</EmployeList>


Assuming that the question asks to output only EMpDetails whose Country child has a string (case-insensitive) value of "India":

I. This XSLT 1.0 transformation:

<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="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "EMpDetails
    [not(translate(Country,
                   'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                   'abcdefghijklmnopqrstuvwxyz'
                   )
         ='india'
         )
    ]
 "/>
</xsl:stylesheet>

when applied on the provided XML document:

<EmployeList>
    <EMpDetails>
        <Name>Kiran</Name>
        <ID>ID001</ID>
        <city>Hyderabad</city>
        <Country>India</Country>
    </EMpDetails>
    <EMpDetails>
        <Name>Sunny</Name>
        <ID>ID002</ID>
        <city>Banglore</city>
        <Country>INDIA</Country>
    </EMpDetails>
    <EMpDetails>
        <Name>John</Name>
        <ID>ID001</ID>
        <city>TEXAS</city>
        <Country>US</Country>
    </EMpDetails>
    <EMpDetails>
        <Name>Raj</Name>
        <ID>ID006</ID>
        <city>Dallas</city>
        <Country>US</Country>
    </EMpDetails>
    <EMpDetails>
        <Name>Nag</Name>
        <ID>ID007</ID>
        <city>ITALY</city>
        <Country>Rome</Country>
    </EMpDetails>
</EmployeList>

produces the wanted, correct result:

<EmployeList>
   <EMpDetails>
      <Name>Kiran</Name>
      <ID>ID001</ID>
      <city>Hyderabad</city>
      <Country>India</Country>
   </EMpDetails>
   <EMpDetails>
      <Name>Sunny</Name>
      <ID>ID002</ID>
      <city>Banglore</city>
      <Country>INDIA</Country>
   </EMpDetails>
</EmployeList>

II. This XSLT 2.0 transformation:

<xsl:stylesheet version="2.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="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "EMpDetails[not(upper-case(Country)='INDIA')]"/>
</xsl:stylesheet>

again produces the same, wanted and correct result.

Explanation: Overriding the identity rule with a template matching all unwanted EMpDetails elements. This template has empty body, which effectively prevents copying any such matched elements to the output.

Remember: Using and overriding the identity rule/template is the most fundamental and most powerful XSLT design pattern.


That should work as you need (assuming that you want all EMpDetails elements where Country is equal to India with case-insensitivity):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="EmployeList">
        <EmployeList>
            <xsl:copy-of select="EMpDetails[lower-case(Country) = 'india']"/>
        </EmployeList>
    </xsl:template>
</xsl:stylesheet>


Assuming your sample input is simple as it's shown you could also go with:

<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:template match="/EmployeList">
        <xsl:copy>
            <xsl:copy-of select="EMpDetails[
                Country[
                .='India'
                or .='INDIA']
                ]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜