User515
User515

Reputation: 186

Removing Space or spaces in the starting of the specific element and consecutive space in between text using xslt

I want remove consecutive spaces to single space and after opening or before closing of particular element space or spaces need to be removed with out effecting sub elements.

Input:

<products>
<product1> Product P  <i>Product</i> Q</product1>
<product1> </product1>
<product2>  Product <b>Q Product R</b>   </product2>
<product2><b></b></product2>
<product3>Product  R  </product3>
<product4> Product S </product4>
<product5>Product T </product5>
</products>

XSLT Tried:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match="*">
       <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates/>
       </xsl:copy>
    </xsl:template>

    <xsl:template match="text()">
        <xsl:value-of select="normalize-space()"/>
    </xsl:template>
    
    
</xsl:transform>

Output:

<products>
   <product1>Product P<i>Product</i>Q
   </product1>
   <product2>Product<b>Q Product R</b></product2>
   <product3>Product R</product3>
   <product4>Product S</product4>
   <product5>Product T</product5>
</products>

Required Output:

<products>
<product1>Product P <i>Product</i> Q</product1>
<product2>Product <b>Q Product R</b></product2>
<product3>Product R</product3>
<product4>Product S</product4>
<product5>Product T</product5>
</products>

Please advise. Thanks in advance.

Upvotes: 0

Views: 90

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167506

I don't think the rules are clear from one example but

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="products/*/text()[not(following-sibling::node()[self::*]) and not(preceding-sibling::node()[self::*])]">
      <xsl:value-of select="normalize-space()"/>
  </xsl:template>
  
  <xsl:template match="products/*/text()[preceding-sibling::node()[self::*]]">
      <xsl:value-of select=". => replace('\s+$', '') => replace('\s+', ' ')"/>
  </xsl:template>
  
    <xsl:template match="products/*/text()[following-sibling::node()[self::*]]">
      <xsl:value-of select=". => replace('^\s+', '') => replace('\s+', ' ')"/>
  </xsl:template>
   
</xsl:stylesheet>

comes closer to your desired result so perhaps you can adapt it to your needs if they are clear.

https://xsltfiddle.liberty-development.net/93nwMoc

Upvotes: 1

Related Questions