简体   繁体   中英

read xml element by excluding its attribute using XSLT

I want to transform the given xml input using XSLT and I want to exclude the "xmlns" attribute of root element from the transformed output

my input xml is

<?xml version="1.0" encoding="ISO-8859-1"?>

<library xmlns="https://support.bridgerinsight.lexisnexis.com/downloads/xsd/4.2/CWLEntityExport.xsd">
 <book>
  <title>Programming in C</title>
  <author>Balagurusamy</author>
  <country>India</country>
  <price>165</price>
  <year>1998</year>
 </book>
 <book>
  <title>Professional ASP.NET 4 in C# and VB</title>
  <author>Bill Evjen, Scott Hanselman, Devin Rader</author>
  <country>USA</country>
  <price>580</price>
  <year>2010</year>
 </book>
 <book>
  <title>Professional Microsoft SQL Server 2008 Programming</title>
  <author>Robert Vieira</author>
  <country>USA</country>
  <price>520</price>
  <year>2009</year>
 </book>
 <book>
  <title>Professional LINQ</title>
  <author>Scott Klein</author>
  <country>USA</country>
  <price>425</price>
  <year>2008</year>
 </book>
</library>

and expected xml output after transformation using XSLT is as follows

<?xml version="1.0" encoding="UTF-8"?>
<BookList>
<Book>
<title>Programming in C</title>
<author>Balagurusamy</author>
<country>India</country>
</Book>
<Book>
<title>Professional ASP.NET 4 in C# and VB</title>
<author>Bill Evjen, Scott Hanselman, Devin Rader</author>
<country>USA</country>
</Book>

<Book>
<title>Professional Microsoft SQL Server 2008 Programming</title>
<author>Robert Vieira</author>
<country>USA</country>
</Book>
<Book>
<title>Professional LINQ</title>
<author>Scott Klein</author>
<country>USA</country>
</Book>

</BookList>

my xslt is

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
  <xsl:template match="/">
    <BookList>
      <xsl:for-each select="library/book">
        <Book>

          <title>
            <xsl:value-of select="title"/>
          </title>
          <author>
            <xsl:value-of select="author"/>
          </author>
          <country>
            <xsl:value-of select="country" />
          </country>

        </Book>
      </xsl:for-each>
    </BookList>
  </xsl:template>
</xsl:stylesheet>

what changes do i need to make in above XSLT to get the given expected output xml?

I want to exclude the "xmlns" attribute of root element from the transformed output

It's not an attribute - it's a namespace declaration. It places all elements in your input XML in a namespace bound to the declared URI.

You need to declare this namespace in your stylesheet, assign it a prefix and use that prefix when addressing elements in the input XML. Without this, your XPath expressions will not select anything.

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns1="https://support.bridgerinsight.lexisnexis.com/downloads/xsd/4.2/CWLEntityExport.xsd"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/ns1:library">
    <BookList>
        <xsl:for-each select="ns1:book">
            <Book>
                <title>
                    <xsl:value-of select="ns1:title"/>
                </title>
                <author>
                    <xsl:value-of select="ns1:author"/>
                </author>
                <country>
                    <xsl:value-of select="ns1:country" />
                </country>
            </Book>
        </xsl:for-each>
    </BookList>
</xsl:template>

</xsl:stylesheet>

I want to transform the given xml input using XSLT and I want to exclude the "xmlns" attribute of root element from the transformed output

my input xml is

 <?xml version="1.0" encoding="ISO-8859-1"?> <library xmlns="https://support.bridgerinsight.lexisnexis.com/downloads/xsd/4.2/CWLEntityExport.xsd"> <book> <title>Programming in C</title> . . . 

A very short, simple and generic way of doing this is :

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output indent="yes"/>
 <xsl:strip-space elements="*"/>

  <xsl:template match="*">
    <xsl:element name="{name()}">
      <xsl:copy-of select="namespace::*[name()]"/>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Do note that no namespace needs to be declared in the transformation and no specific XPath expression is needed!

When this transformation is applied on the provided XML document (or, in general, on any document whose default namespace needs to be eliminated), the wanted, correct result is produced:

<?xml version="1.0" encoding="utf-8"?>
<library>
   <book>
      <title>Programming in C</title>
      <author>Balagurusamy</author>
      <country>India</country>
      <price>165</price>
      <year>1998</year>
   </book>
   <book>
      <title>Professional ASP.NET 4 in C# and VB</title>
      <author>Bill Evjen, Scott Hanselman, Devin Rader</author>
      <country>USA</country>
      <price>580</price>
      <year>2010</year>
   </book>
   <book>
      <title>Professional Microsoft SQL Server 2008 Programming</title>
      <author>Robert Vieira</author>
      <country>USA</country>
      <price>520</price>
      <year>2009</year>
   </book>
   <book>
      <title>Professional LINQ</title>
      <author>Scott Klein</author>
      <country>USA</country>
      <price>425</price>
      <year>2008</year>
   </book>
</library>

Update:

If in addition some renamings of elements are necessary, the transformation becomes:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output indent="yes"/>
 <xsl:strip-space elements="*"/>

  <xsl:template match="*">
    <xsl:element name="{name()}">
      <xsl:copy-of select="namespace::*[name()]"/>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="*[name()='library']">
    <BookList>
      <xsl:apply-templates/>
    </BookList>
  </xsl:template>

  <xsl:template match="*[name()='book']">
    <Book>
      <xsl:apply-templates/>
    </Book>
  </xsl:template>

  <xsl:template match="*[name()='price' or name()='year']"/>
</xsl:stylesheet>

and when applied to the provided XML document, the wanted result is produced:

<?xml version="1.0" encoding="utf-8"?>
<BookList>
   <Book>
      <title>Programming in C</title>
      <author>Balagurusamy</author>
      <country>India</country>
   </Book>
   <Book>
      <title>Professional ASP.NET 4 in C# and VB</title>
      <author>Bill Evjen, Scott Hanselman, Devin Rader</author>
      <country>USA</country>
   </Book>
   <Book>
      <title>Professional Microsoft SQL Server 2008 Programming</title>
      <author>Robert Vieira</author>
      <country>USA</country>
   </Book>
   <Book>
      <title>Professional LINQ</title>
      <author>Scott Klein</author>
      <country>USA</country>
   </Book>
</BookList>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM