retain newline when copying contents of attribute

D

dkacher

Hello -
I'm looking for a way to retain newlines when using XSL to copy the
content of an XML attribute.

I have this XML input:
<?xml version="1.0"?>
<A >
<B x = "stuff" y = "line 1
line 2" />
</A>

I would like to write an XSL stylesheet such that it generates html
which, when opened in a browser, looks like this:

Content of y ==
line 1
line 2
==End of content of y

So it seems like my html should look something like this:
<html>
<body>
<p>
Content of y ==
</p><p>line 1
</p><p>line 2
</p><p>== End of content of y
</p>
</body>
</html>

The question is: how do I write an xsl stylesheet to produce this xml?

I've tried copy-of:

<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
version = "1.0" >
<xsl:eek:utput method = "html" />
<xsl:template match="/">
<html><head></head>
<body>Content of y ==<p>
<xsl:apply-templates select="/A/B"/>
== End of content of y</p>
</body>
</html>
</xsl:template>
<xsl:template match = "B" >
<xsl:copy-of select = "@y" />
</xsl:template>
</xsl:stylesheet>

which produces this output:

<html><head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
</head>
<body>Content of y ==<p y="line 1 line 2">
== End of content of y</p>
</body>
</html>

This has two problems:
The newline is not retained
The content of the attribute y has been placed as an attribute of the p
element!

Any suggestions on how to tackle this would be appreciated.

Thanks,
- Don
 
M

Martin Honnen

dkacher wrote:

<?xml version="1.0"?>
<A >
<B x = "stuff" y = "line 1
line 2" />

I would like to write an XSL stylesheet such that it generates html
which, when opened in a browser, looks like this:

Content of y ==
line 1
line 2
==End of content of y
<xsl:template match = "B" >
<xsl:copy-of select = "@y" />

How about using the HTML pre element
<xsl:template match="B">
<pre><xsl:value-of select="@y" /></pre>
</xsl:template>
if you want to preserve white space.

Otherwise you need (with XSLT 1.0) a recursive template that processes
@y and takes the string before a line break and wraps it into a HTML p
element, then calls itself with the remaining string.
 
D

dkacher

Hi Martin -
Thanks for the suggestion. Maybe I implemented it incorrectly -- it
appears that (at least inXselerator) the content of an attribute is
normalized automatically when you select it. This doesn't happen to the
content of an element. Here's my test:

The xml:
<a>
<b x="111" y="222
333">44
55</b>
</a>

The xsl:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput method="html"/>
<xsl:template match="/">
1.1. @/a/b/@y selected into a variable:
<xsl:variable name="y" select="a/b/@y"></xsl:variable>
<pre>
<xsl:value-of select="$y"/>
</pre>
:/a/b/@y selected into a variable
<br/>
<br/>
2.1. /a/b selected into a variable:
<xsl:variable name="b" select="a/b"></xsl:variable>
<pre>
<xsl:value-of select="$b"/>
</pre>
:/a/b selected into a variable
<br/>
<br/>
</xsl:template>
</xsl:stylesheet>

And the result:
1.1. @/a/b/@y selected into a variable:
<pre>222 333</pre>
:/a/b/@y selected into a variable
<br><br>
2.1. /a/b selected into a variable:
<pre>44
55</pre>
:/a/b selected into a variable
<br><br>

My goal, however, is to get the following for 1.1:
1.1. @/a/b/@y selected into a variable:
<pre>222
333</pre>
:/a/b/@y selected into a variable
<br><br>

-------

(Later) I've done a bit more research, and now think that I won't be
able to achieve my goal directly via XSL. According to the XSL
standard, an attribute's content is _always_ normalized, and there's no
way to act on its non-normalized state. So I think I'm stuck. I think
I'll have to write a filter that transforms
<a>
<b x="111" y="222
333">44
55</b>
</a>
to
<a>
<b x="111"> <y>222
333</y>44
55</b>
</a>
and then feed that to a stylesheet that copies the element y.
Do you agree?
Thanks,
- Don
 
J

Joe Kesselman

See the XML spec. Whitespace in attribute values gets normalized. If
that isn't what you want, put the value in a child element rather than
an attribute.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top