[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: How to remove (in addition) empty attributes?
Ben,
As so often, the problem here is in the specification. You have solved the problems of removing elements according to one rule: 1. elements that have no content (child nodes) and of attributes according to another: 2. attributes that have no value but not of removing elements defined as "empty" according to a third: 3. elements that contain only elements and attributes that would removed (by any rule). You do infer that since your third rule is recursive, a full solution will also be recursive. If you can rewrite rule 3 so it doesn't invoke itself, you can write a transform that doesn't have to process its own results recursively. For example, you might say: 3a. elements none of whose attributes have values and whose children are empty (have no children) -- but of course 3a will fail if your containment of such elements goes deeper than two. Here's a recursive solution (note: XSLT 2.0 only). It works by passing the tree through a set of "scrubbing" templates, and also through a set of copying templates, repeating as necessary until both results are the same. It assumes you don't have any whitespace-only text nodes you want to preserve: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/|*|@*|text()" mode="copy scrub"> <xsl:copy> <xsl:apply-templates select="*|@*|text()" mode="#current"/> </xsl:copy> </xsl:template> <xsl:template match="*[empty(*|text()|@*[normalize-space()])]" mode="scrub"/> <xsl:template match="@*[not(normalize-space())]" mode="scrub"/> <xsl:template match="/"> <xsl:variable name="scrubbed"> <xsl:apply-templates select="." mode="scrub"/> </xsl:variable> <xsl:variable name="copied"> <xsl:apply-templates select="." mode="copy"/> </xsl:variable> <xsl:choose> <xsl:when test="deep-equal($scrubbed, $copied)"> <xsl:sequence select="$scrubbed"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="$scrubbed"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> Tested only lightly.... Cheers, Wendell At 02:40 AM 12/3/2009, you wrote: The problem with this is that only elements OR attributes are stripped but not both at the same time. ====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|