 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

May 21st, 2009, 04:10 AM
|
|
Authorized User
|
|
Join Date: May 2009
Posts: 15
Thanks: 6
Thanked 0 Times in 0 Posts
|
|
Removing attribute xsi:nil=true
I have a requirement where i need to remove the empty elements and the elements with attribute xsi:nil=' true" in my received xml.
My expected input format:
===================
<emp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<emp2 sno='2'>
<name>Vijay</name>
<country>Australia</country>
<company/>
<dept>
<deptno>1</deptno>
<deptname>RND</deptname>
</dept>
</emp2>
<emp1 sno='3'>
<name>Chandra</name>
<country>India</country>
<company>B</company>
<dept>
<deptno xsi:nil="true"/>
<deptname>Dev</deptname>
</dept>
</emp1>
</emp>
My desired output:
==============
<?xml version = '1.0' encoding = 'UTF-8'?>
<emp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<emp2 sno="2">
<name>Vijay</name>
<country>Australia</country>
<dept>
<deptno>1</deptno>
<deptname>RND</deptname>
</dept>
</emp2>
<emp1 sno="3">
<name>Chandra</name>
<country>India</country>
<company>B</company>
<dept>
<deptname>Dev</deptname>
</dept>
</emp1>
</emp>
My xsl code:
===========
<xsl:template match="@*|node()">
<xsl:if test=". != '' or ./@* != '' or ./@xsi:nil='true'">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
Current output:
============
<?xml version = '1.0' encoding = 'UTF-8'?>
<emp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<emp2 sno="2">
<name>Vijay</name>
<country>Australia</country>
<dept>
<deptno>1</deptno>
<deptname>RND</deptname>
</dept>
</emp2>
<emp1 sno="3">
<name>Chandra</name>
<country>India</country>
<company>B</company>
<dept>
<deptno xsi:nil="true"/>
<deptname>Dev</deptname>
</dept>
</emp1>
</emp>
Can anyone help me to get rid of the element with xsi:nil in the payload.
|
|

May 21st, 2009, 04:22 AM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
|
|
Shouldn't your test be
Code:
not(xsi:nil = 'true')
as you said you want to copy if it's not nil?
I'm not sure why you have the
part, that doesn't seem to be in the requirement. Why not
Code:
. =!= '' or not(xsi:nil = 'true')
?
|
|

May 21st, 2009, 04:25 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
Rather than having a single template rule with an xsl:if inside it, use multiple template rules. That's what rule-based programming is about.
Then you just need the rule
<xsl:template match="*[@xsi:nil='true']"/>
to get rid of these elements.
Your existing logic is flawed. You're copying elements if xsi:nil is true, whereas you want to do the opposite. And the condition (./@* != '' or ./@xsi:nil='true') doesn't make any sense, because if @xsi:nil="true" is true, then the first condition @* != '' will also be true - it tests whether there is at least one attribute whose value is non-empty.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|
The Following User Says Thank You to mhkay For This Useful Post:
|
|
|

May 21st, 2009, 04:38 AM
|
|
Friend of Wrox
|
|
Join Date: Jun 2008
Posts: 291
Thanks: 9
Thanked 29 Times in 29 Posts
|
|
Try this:
Code:
<xsl:template match="*">
<xsl:if test=". != ''">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates></xsl:apply-templates>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="*[@xsi:nil='true']"/>
__________________
Rummy
|
|
The Following User Says Thank You to mrame For This Useful Post:
|
|
|

May 21st, 2009, 04:46 AM
|
|
Authorized User
|
|
Join Date: May 2009
Posts: 15
Thanks: 6
Thanked 0 Times in 0 Posts
|
|
Hi joefawcett i added this condition ./@* != '' because i may have other elements with attributes which should not be removed. I haven't mentioned it in the above requirement. Yes my condition is wrong.
Thanks mhkay i am trying that multiple template rule approach
|
|

May 21st, 2009, 04:59 AM
|
|
Authorized User
|
|
Join Date: May 2009
Posts: 15
Thanks: 6
Thanked 0 Times in 0 Posts
|
|
Hi mrame sorry i havent seen ur message. Yes it works for me Thanks Michael and Rummy. But i have a doubt here we used two templates. If the element is not null we are copying it and the apply templates is called and it will call the other template before the copy is completed in which it will remove the xsi:nil? Is this correct?
|
|

May 21st, 2009, 05:10 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
>If the element is not null we are copying it and the apply templates is called and it will call the other template before the copy is completed in which it will remove the xsi:nil?
I'm not sure quite what you mean. I think you haven't fully understood template rules. When you select nodes in apply-templates, each node is processed by one template rule, the one whose pattern is the best match. So if xsl:nil='true' it will choose the empty template rule (effectively deleting the element), otherwise it will choose the identity template rule (effectively copying the element).
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

May 21st, 2009, 05:29 AM
|
|
Authorized User
|
|
Join Date: May 2009
Posts: 15
Thanks: 6
Thanked 0 Times in 0 Posts
|
|
Thanks Michael i got it now.
|
|

September 2nd, 2009, 12:00 PM
|
|
Authorized User
|
|
Join Date: Sep 2009
Posts: 14
Thanks: 6
Thanked 0 Times in 0 Posts
|
|
I get an error indicating "invalid prefix error in xpath expression, invaid prefix" in xmlspy when I apply this xsl. The part
Code:
match="*[@xsi:nil='true']"
is highlighted. My complete xsl follows. Please advise. I simply want to remove all elements with the xsl:nil attribute. Thanks.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@xsi:nil='true']"/>
</xsl:stylesheet>
|
|

September 2nd, 2009, 12:04 PM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
|
|
where are you declaring the xsi namespace prefix?
|
|
The Following User Says Thank You to samjudson For This Useful Post:
|
fixit (September 2nd, 2009)
|
|
 |