Jump to content

Processing of text() and node()


webbenny

Recommended Posts

Hello there!I've the following XML structure here:

<list>	<item>Enter your name at field <emphasis>name</emphasis>.</item>	<item>Enter your <emphasis>Passwort</emphasis>.</item>	<item>Confirm with <emphasis>OK</emphasis>.<para>The system checks the password.</para>		<para>Follow the instructions.</para>	</item></list>

After the tranformation the result should be:

<itemizedlist>	<listitem><para>Enter your name at field <em>name</em>.</para></listitem>	<listitem><para>Enter your <em>Passwort</em>.</para></listitem>	<listitem><para>Confirm with <em>OK</em>.</para><para>The system checks the password.</para>		<para>Follow the instructions.</para>	</listitem></itemizedlist>

My current stylesheet is:

	<xsl:template match="emphasis">		<xsl:element name="em">			<xsl:apply-templates/>		</xsl:element>	</xsl:template>	<xsl:template match="list">		<xsl:element name="itemizedlist">			<xsl:apply-templates/>		</xsl:element>	</xsl:template>	<xsl:template match="item">		<xsl:element name="listitem">			<xsl:choose>				<xsl:when test="./para and ./text()">					<xsl:if test="parent::item"></xsl:if>					<xsl:if test="./text()">						<xsl:element name="para">							<xsl:value-of select="./text()"/>						</xsl:element>					</xsl:if>				</xsl:when>				<xsl:when test="item[child::node() != 'para']">					<xsl:apply-templates/>				</xsl:when>				<xsl:otherwise>					<xsl:element name="para">						<xsl:apply-templates/>					</xsl:element>				</xsl:otherwise>			</xsl:choose>		</xsl:element>	</xsl:template>

The requirements are:* Each listitem content MUST be in a para!* The element in item an para MUST be processed by the stylesheetWith that stylesheet I always run in trouble, if the item element has text AND child elements.Has anybody some ideas for that case? Thank you very much..Regards, webbenny

Link to comment
Share on other sites

Here is an XSLT 2.0 stylesheet:

<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="2.0">    <xsl:template match="@* | node()">	<xsl:copy>	  <xsl:apply-templates select="@* | node()"/>	</xsl:copy>  </xsl:template>    <xsl:template match="emphasis">	<em>	  <xsl:apply-templates/>	</em>  </xsl:template>    <xsl:template match="list">	<itemizedlist>	  <xsl:apply-templates/>	</itemizedlist>  </xsl:template>    <xsl:template match="item">	<listitem>	  <xsl:for-each-group select="node()" group-adjacent="boolean(self::para)">		<xsl:choose>		  <xsl:when test="current-grouping-key()">			<xsl:apply-templates select="current-group()"/>		  </xsl:when>		  <xsl:otherwise>			<para>			  <xsl:apply-templates select="current-group()"/>			</para>		  </xsl:otherwise>		</xsl:choose>	  </xsl:for-each-group>	</listitem>  </xsl:template>  </xsl:stylesheet>

When I use Saxon 9.3 on the input

<list><item>Enter your name at field <emphasis>name</emphasis>.</item><item>Enter your <emphasis>Passwort</emphasis>.</item><item>Confirm with <emphasis>OK</emphasis>.<para>The system checks the password.</para><para>Follow the instructions.</para></item></list>

I get the following result

<?xml version="1.0" encoding="UTF-8"?><itemizedlist><listitem><para>Enter your name at field <em>name</em>.</para></listitem><listitem><para>Enter your <em>Passwort</em>.</para></listitem><listitem><para>Confirm with <em>OK</em>.</para><para>The system checks the password.</para><para></para><para>Follow the instructions.</para><para></para></listitem></itemizedlist>

I think this does what you want, with the exception of also wrapping pure white space content into "para" elements. I am not sure whether you want that, you said "Each listitem content MUST be in a para!" but your requested output sample does not do that for white space text nodes between para elements.

Link to comment
Share on other sites

Here is an XSLT 2.0 stylesheet:
<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="2.0">    <xsl:template match="@* | node()">	<xsl:copy>	  <xsl:apply-templates select="@* | node()"/>	</xsl:copy>  </xsl:template>    <xsl:template match="emphasis">	<em>	  <xsl:apply-templates/>	</em>  </xsl:template>    <xsl:template match="list">	<itemizedlist>	  <xsl:apply-templates/>	</itemizedlist>  </xsl:template>    <xsl:template match="item">	<listitem>	  <xsl:for-each-group select="node()" group-adjacent="boolean(self::para)">		<xsl:choose>		  <xsl:when test="current-grouping-key()">			<xsl:apply-templates select="current-group()"/>		  </xsl:when>		  <xsl:otherwise>			<para>			  <xsl:apply-templates select="current-group()"/>			</para>		  </xsl:otherwise>		</xsl:choose>	  </xsl:for-each-group>	</listitem>  </xsl:template>  </xsl:stylesheet>

When I use Saxon 9.3 on the input

<list><item>Enter your name at field <emphasis>name</emphasis>.</item><item>Enter your <emphasis>Passwort</emphasis>.</item><item>Confirm with <emphasis>OK</emphasis>.<para>The system checks the password.</para><para>Follow the instructions.</para></item></list>

I get the following result

<?xml version="1.0" encoding="UTF-8"?><itemizedlist><listitem><para>Enter your name at field <em>name</em>.</para></listitem><listitem><para>Enter your <em>Passwort</em>.</para></listitem><listitem><para>Confirm with <em>OK</em>.</para><para>The system checks the password.</para><para></para><para>Follow the instructions.</para><para></para></listitem></itemizedlist>

I think this does what you want, with the exception of also wrapping pure white space content into "para" elements. I am not sure whether you want that, you said "Each listitem content MUST be in a para!" but your requested output sample does not do that for white space text nodes between para elements.

Wow! It works great! I don't even know the "for-each-group" functionality in xsl... ;-) But one more reason to learn all that..The wrapping of white space content into para elements is also required, so it fits perfect for my case.Thank you so much!
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...