 |
| 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
|
|
|
|

September 18th, 2012, 01:43 AM
|
|
Authorized User
|
|
Join Date: Jul 2010
Posts: 74
Thanks: 23
Thanked 0 Times in 0 Posts
|
|
How to remove the father element if the child elements are empty
There are several loop father nodes which contain several child elements, like below:
Quote:
<?xml version="1.0" encoding="utf-8" ?>
<ns0:PO xmlns:ns0="http://HelloWorld.POSchema">
<PO_Number>16</PO_Number>
<Total>PO_Number1234</Total>
<PO_Number2>6</PO_Number2>
<PO_Number3>5</PO_Number3>
<PORoot>
<PORoot1>PORoot1</PORoot1>
<PORoot2>PORoot2</PORoot2>
<POChild>
<POChild1>POChild1</POChild1>
<POChild2>POChild2</POChild2>
</POChild>
<PORoot1>PORoot3</PORoot1>
<PORoot2>PORoot4</PORoot2>
<POChild>
<POChild1>POChild3</POChild1>
<POChild2></POChild2>
</POChild>
<PORoot1>PORoot5</PORoot1>
<PORoot2>PORoot6</PORoot2>
<POChild>
<POChild1></POChild1>
<POChild2></POChild2>
</POChild>
<PORoot1></PORoot1>
<PORoot2></PORoot2>
<POChild>
<POChild1></POChild1>
<POChild2></POChild2>
</POChild>
</PORoot>
</ns0:PO>
|
What I want to do is that I want to remove all the empty POChild nodes, if the two child POChild1/2 nodes are empty, remove the father node POChild as well.
I have no idea how to achive this.
The output xml should be like below, but probably a little different:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<PO>
<PO_Number>16</PO_Number>
<Total>PO_Number1234</Total>
<PO_Number2>6</PO_Number2>
<PO_Number3>5</PO_Number3>
<PORoot>
<PORoot1>PORoot1</PORoot1>
<PORoot2>PORoot2</PORoot2>
<POChild>
<POChild1>POChild1</POChild1>
<POChild2>POChild2</POChild2>
</POChild>
<PORoot1>PORoot3</PORoot1>
<PORoot2>PORoot4</PORoot2>
<POChild>
<POChild1>POChild3</POChild1>
</POChild>
<PORoot1>PORoot5</PORoot1>
<PORoot2>PORoot6</PORoot2>
</PORoot>
</PO>
ATTENTION: The first node is ns0:PO with xmlns.
Thank you so much in advance!
Last edited by JohnKiller; September 18th, 2012 at 01:50 AM..
|
|

September 18th, 2012, 04:45 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
You want a transformation that defines an identity rule to copy elements by default:
Code:
<xsl:template match="*">
<xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>
and then rules to avoid copying POChild, POChild1, and POChild2 elements if they have no text content:
Code:
<xsl:template match="n:POChild[not(normalize-space())]"/>
<xsl:template match="n:POChild1[not(normalize-space())]"/>
<xsl:template match="n:POChild2[not(normalize-space())]"/>
The namespace prefix "n" should be bound to the right namespace by adding
xmlns:n="http://HelloWorld.POSchema"
to your xsl:stylesheet element. Of course you can use a different namespace prefix if you prefer.
__________________
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:
|
|
|

September 18th, 2012, 06:13 AM
|
|
Authorized User
|
|
Join Date: Jul 2010
Posts: 74
Thanks: 23
Thanked 0 Times in 0 Posts
|
|
Hello Michael,
Thank you for your reply.
Is there any way to put them in one template, like we deal with the node without namespace? <xsl:template match="PO">
|
|

September 18th, 2012, 06:24 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
Why on earth would you want to put code in a single template when it can be broken up cleanly into several independent templates?
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

September 18th, 2012, 06:30 AM
|
|
Authorized User
|
|
Join Date: Jul 2010
Posts: 74
Thanks: 23
Thanked 0 Times in 0 Posts
|
|
Since I really do not know how to assemble all the templates together, and the relationships among them. The material which I found online make me confusing. And when I tested the templates, it cannot work right.
|
|

September 18th, 2012, 04:24 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
>The material which I found online make me confusing
Did you know that Wrox publishes books on XML, and that this forum is primarily intended for readers of those books?
If you're not used to learning from books, I can really recommend it. Unlike most online resources, books are carefully designed, written, edited, and proofread, and Wrox has a high reputation for the quality of the reviewers who ensure that the material is consistent, correct, and well-presented.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

September 18th, 2012, 07:40 PM
|
|
Authorized User
|
|
Join Date: Jul 2010
Posts: 74
Thanks: 23
Thanked 0 Times in 0 Posts
|
|
Sound great! Yes, I have several Wrox books, but no one is related to XML and XSLT.
I searched Wrox Bookstore/E-Books, there are a lot of books related to XML and XSLT. Would you give me recommendation which book is better?
Thank you!
|
|

October 18th, 2012, 09:50 AM
|
|
Registered User
|
|
Join Date: Oct 2012
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Solution
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://HelloWorld.POSchema">
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:apply-templates select="ns0:PO"/>
</xsl:template>
<xsl:template match="ns0:PO">
<xsl:element name="PO">
<xsl:copy-of select="child::* except PORoot" copy-namespaces="no"/>
<xsl:apply-templates select="PORoot"/>
</xsl:element>
</xsl:template>
<xsl:template match="PORoot">
<xsl:element name="PORoot">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="POChild">
<xsl:if test="child::* and child::*[text()!=' ']">
<xsl:element name="POChild">
<xsl:for-each select="child::*">
<xsl:if test="text()!= ' '">
<xsl:copy-of select="." copy-namespaces="no"/>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template match="PORoot1">
<xsl:if test="text()!=' '">
<xsl:element name="PORoot1">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template match="PORoot2">
<xsl:if test="text()!=' '">
<xsl:element name="PORoot2">
<xsl:value-of select="."/>
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
|
|
 |