Subject: [xsl] XSL to generate XPaths From: Michael Strasser <M.Strasser@xxxxxxxxxxxxx> Date: Wed, 16 May 2001 09:26:38 +1000 |
This XSL document generates a text list of all XPaths of element and attribute nodes in an XML document. XPaths are unique and only include subscripts when necessary. I created this over the past couple of weeks to use in a project I'm working on. Here it is for anybody else who may find it useful. You can, of course, change the delimiter from newline ( ) to anything else (like a comma). All comments welcome. Sorry about e-mail line-wrapping. Have fun! -- Michael Strasser Brisbane, Australia --- snip --- <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- all-xpaths.xsl Transform an XML document to a text listing of all its element and attribute nodes as unique XPath specifications. Output is a newline-separated list. Michael Strasser, May 2001 M.Strasser@xxxxxxx --> <!-- Output is plain text. --> <xsl:output method="text" media-type="text/plain"/> <!-- Root element match: apply to all child nodes. --> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <!-- Element and attribute match: this is where the work is done. --> <xsl:template match="*|@*"> <xsl:param name="path" select="''"/> <!-- Create this node's XPath specifier by appending information to the path param passed to this template. A variable is created because its value is used twice. This code is a bit complicated to make the output a bit pretty: if a node has no siblings with the same name there is no need to include a subscript to make the XPath unique. --> <xsl:variable name="this-path"> <xsl:value-of select="concat($path, '/')"/> <!-- If this is an attribute node, output '@' before its name. --> <xsl:if test="../@*[name() = name(current())]"> <xsl:text>@</xsl:text> </xsl:if> <xsl:value-of select="name()"/> <!-- If the parent has more than one node with the same name as the current one... --> <xsl:if test="count(../*[name() = name(current())]) > 1"> <!-- Include the current node's subscript in the list of those with the same name. --> <xsl:value-of select="concat('[', count(preceding-sibling::*[name() = name(current())]) + 1, ']')"/> </xsl:if> </xsl:variable> <!-- If this is not the first node in the document, output a newline first. --> <xsl:if test="preceding::*|ancestor::*"> <xsl:text> </xsl:text> </xsl:if> <!-- Send this node's path to the output stream now. --> <xsl:value-of select="$this-path"/> <!-- Apply to this node's children, passing its path as a starting point. --> <xsl:apply-templates select="*|@*"> <xsl:with-param name="path" select="$this-path"/> </xsl:apply-templates> </xsl:template> <!-- Ignore comment, text and PI nodes. --> <xsl:template match="comment()|text()|processing-instruction()"/> </xsl:stylesheet> XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] XPath for number of prece, Christopher R. Maden | Thread | Re: [xsl] XSL to generate XPaths, Michael Strasser |
[xsl] XPath for number of preceding, Michael Strasser | Date | RE: [xsl] Calculating column widths, Michael Kay |
Month |