[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: one line of xml to indented xml doc

Subject: Re: one line of xml to indented xml doc
From: Peter Davis <pdavis152@xxxxxxxxx> (by way of Peter Davis <pdavis152@xxxxxxxxx>)
Date: Sun, 24 Mar 2002 13:32:12 -0800
next line in xml
Is indent="yes" not working?  It sounds like that should take care of it.  If
all you mean by "heirarchial structure" is "indent", then this might work:

<xsl:template match="node()">
  <xsl:param name="depth" select="0"/>
  <xsl:call-template name="indent">
    <xsl:with-param name="count" select="$depth"/>
  </xsl:call-template>
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="node()">
      <xsl:with-param name="depth" select="$depth + 1"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="@*">
  <xsl:copy/>
</xsl:template>

<xsl:template name="indent">
  <xsl:param name="count" select="0"/>
  <xsl:if test="$count > 0">
    <xsl:text>    </xsl:text>
    <xsl:call-template name="indent">
      <xsl:with-param name="count" select="$count - 1"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

Each time a node() is matched, it gets the current depth of the node as a
param and calls a recursive "indent" template.  The indent template outputs
four spaces and then calls itself again and again until $count = 0, each time
subtracting 1 from count.

Then the main node() template copies all of the attributes (using
<xsl:copy-of select="@*"/> instead of the <xsl:apply-templates/> and another
"@*" template is an option).  It then outputs a newline character so that the
next node will show up on the next line.  Finally, calls itself on all of its
child nodes, which repeats the whole process, but this time with $depth + 1
so that the "indent" template will output one more set of spaces.

On Sunday 24 March 2002 12:32, Astor Rivera wrote:
> Thanks for the help, although I may not have explained what I really
> needed. You did point out some redundancy I found later that evening.
> What I was trying to transform is a single line of xml being output from a
> C++ app,
> I must then take it and make it a well formed document with a hierachical
> structure
> and the transform is being done using MSXSL.
>
> It must remain generic as the output tags will always vary.
>
> Here is what I have up to now,
>
> <?xml version="1.0"?>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
> <xsl:template match=" * | @* ">
> <xsl:copy>
>         <xsl:apply-templates select=" * | @* " />
> </xsl:copy>
> </xsl:template>
> </xsl:stylesheet>
>
> Although I am currently looking into using xsl:key to generate the
> hierarchical structure.
>
> Any more help is great.
>
> Thanks,
> Astor
>
>
>
> -----Original Message-----
> From: Peter Davis
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Sent: 3/24/02 2:26 AM
> Subject: Re:  one line of xml to indented xml doc
>
> On Friday 22 March 2002 15:52, Astor Rivera wrote:
> > This is what I have and would like to know how to indent the document.
> > The xml is coming from an application, and it's url encoded.
>
> So you have a source document that is not indented, and you want to
> indent
> it?  Well, if that's the case, then you have the right idea with
> <xsl:output
> indent="yes"/>.  The problem is that processors aren't required to
> support
> that; I know that Xalan doesn't do a very good job of it.  Saxon does,
> however.  Your milage will probably vary, though.
>
> BTW, your template has some very redundant parts:
> > <?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:output method="xml" indent="yes" encoding="UTF-8"/>
> > ????????<xsl:template match=" * | node() | text() | @* ">
>
> "text()" and "*" are both redundant since they are matched by "node()".
> So
> really, the only thing you need here is <xsl:template match="node() |
> @*"/>.
>
> > ????????????????????????<xsl:copy>
> > ????????????????????????????????<xsl:apply-templates ?select=" * |
>
> node() |
>
> > @*"/>????????????????????????????</xsl:copy>
>
> Same thing with your apply-templates.  "*" is taken care of by "node()",
> so
> all you need is <xsl:apply-templates select="@* | node()"/>.
>
> > ????????</xsl:template>
> > </xsl:stylesheet>
>
> Your question was a little confusing, so if this is not the answer you
> wanted
> you really should clarify what you mean by "indent".  I would also
> suggest
> re-indenting your stylesheet, because it's pretty ugly with the
> <xsl:copy>
> half way across the page :).  Or maybe that's where your having problems
> with
> indenting?  If so, please clarify.

--
Peter Davis
If you aren't rich you should always look useful.
		-- Louis-Ferdinand Celine

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.