xsl-list
[Top] [All Lists]

Re: [xsl] problem with transforming mixed content

2020-08-16 13:33:07
Dear Mukul,

Thank you for your reply! Yesterday, by tweaking the "type (a)" solution proposed by Graydon, I came up with a solution that is basically the same as yours, with the difference that I had not considered the possibility of attributes on the markup elements. I will add that now to my solution, as suggested by your solution.

As for getting rid of namespace declarations, that can be done by replacing, in the last template, <xsl:copy> with <xsl:element name="{local-name()}">, as Martin pointed out.

Best,
Wolfhart


On 16.08.20 14:19, Mukul Gandhi gandhi(_dot_)mukul(_at_)gmail(_dot_)com wrote:
On Sat, Aug 15, 2020 at 9:33 PM Wolfhart Totschnig wolfhart(_dot_)totschnig(_at_)mail(_dot_)udp(_dot_)cl <mailto:wolfhart(_dot_)totschnig(_at_)mail(_dot_)udp(_dot_)cl> <xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com <mailto:xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com>> wrote:

    But I am still curious: What would an approach of type (a) look
    like in my case? It seems to me that implementing this approach
    would again face the original problem: "turning the punctuation
    into markup" sounds like a description of the original problem.


I've come up with following seemingly correct XSLT transform, that uses approach of type (a) suggested within this thread,

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:xs="http://www.w3.org/2001/XMLSchema";
 exclude-result-prefixes="xs">

   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="title">
      <result>
         <xsl:variable name="result_pass1" as="element()">
            <temp>
              <xsl:apply-templates select="node()" mode="pass1"/>
            </temp>
         </xsl:variable>
         <title>
            <xsl:copy-of select="$result_pass1/colon/preceding-sibling::node()"/>
         </title>
         <subtitle>
            <xsl:copy-of select="$result_pass1/colon/following-sibling::node()"/>
         </subtitle>
      </result>
   </xsl:template>
   <xsl:template match="text()[contains(., ':')]" mode="pass1">
      <xsl:value-of select="lower-case(replace(substring-before(., ':'), '\s+$', ''))"/>
      <colon/>
      <xsl:value-of select="lower-case(replace(substring-after(., ':'), '^\s+', ''))"/>
   </xsl:template>
   <xsl:template match="text()" mode="pass1">
      <xsl:value-of select="lower-case(.)"/>
   </xsl:template>
   <xsl:template match="*" mode="pass1">
      <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates mode="pass1"/>
      </xsl:copy>
   </xsl:template>

</xsl:stylesheet>

This is again a two pass solution. In the first pass, the ':' character is transformed into the markup <colon/>, and the second pass (using the first pass's result) produces the final result.

As also suggested, the above XSLT transform can also handle any number of differently named markups (that can optionally have any number of attributes) before and after the ':' character.

I've also yet not considered XML namespaces mentioned within the use case.


--
Regards,
Mukul Gandhi
XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/2652055> (by email <>)
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--
<Prev in Thread] Current Thread [Next in Thread>