0

I am trying to translate white space by "-". Data come from TEI-XML data:

<m type="base"> 
  <m type="baseForm">A<c type="infix">B</c>CD</m> 
 </m>

and XSL file:

<?xml version="1.0" encoding="UTF-8"?>

  <xsl:for-each select="descendant::m[@type='base']/m[@type='baseForm']">  
    <xsl:choose>
      <xsl:when test="current()/c"><xsl:value-of select="current()[not != c[@type['infix']]] |node()"/></xsl:when>
     <xsl:otherwise><xsl:value-of select="current()"/></xsl:otherwise>
    </xsl:choose>
    <!-- my attempt -->
    <xsl:value-of select="translate(., ' ','-')"/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

Following answer of this post XSL replace space with caret, I have used translate, but it doesn't work. The result should be: "A-B-CD" but I have "A B CD."

Thanks for your kind help.

Vanessa
  • 121
  • 12
  • 2
    `translate` allows you to replace a character by another but frankly in the sample `ABCD` I don't see any space at all so what do you want to achieve with with the `translate(., ' ','-')` where the second argument is a blank space? – Martin Honnen Dec 17 '17 at 19:56
  • Yes, I know there is no space in the `TEI-XML` but unfortunately, the output is with space. I don't know why... – Vanessa Dec 17 '17 at 20:23
  • 2
    You use , where current() is an "m"-node that contains several text nodes. By default, xsl:value-of uses blanks as separator (see here: https://www.w3.org/TR/xslt/#constructing-simple-content). – Fabian Dec 17 '17 at 20:41
  • A more general remark: I suggest that you organize your stylesheet as several templates. Define a specific template for c[@type='infix'] that gives you -B- (in your example). Let xsl:apply-templates do the magic. – Fabian Dec 17 '17 at 20:51
  • 2
    @Vanessa The problem is that you are using inside loop, but not whole output - you need to put logic inside variable and perform translate function with this variable after. Please see my answer. – Alex Fomin Dec 17 '17 at 21:38

2 Answers2

2

As I can predict, problem with spaces will be when XML is beatified as below:

<?xml version="1.0" encoding="UTF-8"?>
<m type="base"> 
  <m type="baseForm">
      A
      <c type="infix">
          B
      </c>
      CD
  </m> 
 </m>

In that case your logic can be put inside variable and then performed translate function, see XSL below:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" />
    <xsl:template match="/">
        <!--put your logic in variable-->
        <xsl:variable name="str">
            <xsl:for-each select="descendant::m[@type='base']/m[@type='baseForm']">
                <xsl:value-of select="."/>
            </xsl:for-each>
        </xsl:variable>
    <!--normalize space will prevent spaces from left and right of string, then all spaces inside will be replaced by '-' -->
    <xsl:value-of select="translate(normalize-space($str), ' ', '-')"/>
 </xsl:template>
</xsl:stylesheet>

Result will be as expected:

A-B-CD
Alex Fomin
  • 485
  • 4
  • 7
  • Excellent! I just replace `select="." />` by `select="current()[not != c[@type['infix']]] |node()"/>` and it works. Thank you @O.F. – Vanessa Dec 17 '17 at 21:44
0

We can replace also using template and only translate once:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="text()" priority="2">
    <xsl:value-of select="translate(., &quot; &quot;, &quot;,&quot;)" />
  </xsl:template>
  <xsl:template match="/">
        <xsl:element name="Your1stNode">
          <xsl:apply-templates select="Your1stNode/text()" />
        </xsl:element>
        <xsl:element name="Your2ndNode">
          <xsl:apply-templates select="Your2ndNode/text()" />
        </xsl:element>
   </xsl:template>
</xsl:stylesheet>

You can replace all space with Comma by using text() in entire document.

Shuvra
  • 199
  • 11