2

I have x xml like this,

<doc>
<p>ABC Number 132, Decimal 321, AAB Double 983 DEF GHI 432 JKL</p>
</doc>

what my objective is if 'Number', 'Decimal', 'Double' followed by a space (' ') followed by a number, then that middle space value should be replaced by a * character.

So the output should be,

<doc>
    <p>ABC Number*132, Decimal*321, AAB Double*983 DEF GHI 432 JKL</p>
</doc>

I have following xsl for this,

<xsl:template match="p">
        <xsl:analyze-string select="text()" regex="(Number/s/d)|(Decimal/s/d)|(Double/s/d)">
            <xsl:matching-substring>
                <xsl:choose>
                    <xsl:when test="regex-group(1)">
                        <xsl:value-of select="'Number*'"/>
                    </xsl:when>
                    <xsl:when test="regex-group(2)">
                        <xsl:value-of select="'Decimal*'"/>
                    </xsl:when>
                    <xsl:when test="regex-group(3)">
                        <xsl:value-of select="'Double*'"/>
                    </xsl:when>
                </xsl:choose>
            </xsl:matching-substring>

            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>

But it does not return the correct result..

Any suggestions how can I modify my code to get the correct output?

1
  • What result does it return? Always tell us what's not working. "It's not working" is insufficient. Commented Apr 30, 2016 at 3:26

2 Answers 2

5

The main issue in your regex is that you're trying to match space and digit with /s and /d.

It should be \s and \d.

However, even if you fixed this you would still lose the digit because you're not capturing it.

You're also losing the p element.

I'd suggest a little simpler regex and adding xsl:copy to keep the p...

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="p">
    <xsl:copy>
      <xsl:analyze-string select="." regex="(Number|Decimal|Double)\s(\d)">
        <xsl:matching-substring>
          <xsl:value-of select="concat(regex-group(1),'*',regex-group(2))"/>
        </xsl:matching-substring>
        <xsl:non-matching-substring>
          <xsl:value-of select="."/>
        </xsl:non-matching-substring>
      </xsl:analyze-string>      
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Output

<doc>
   <p>ABC Number*132, Decimal*321, AAB Double*983 DEF GHI 432 JKL</p>
</doc>
Sign up to request clarification or add additional context in comments.

Comments

2

Much simpler and shorter:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="p/text()">
    <xsl:value-of select="replace(., '(Number|Decimal|Double) (\d+)', '$1*$2')"/>
  </xsl:template>
</xsl:stylesheet>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.