xsl-list
[Top] [All Lists]

Re: [xsl] [XSL] weird issue - <xsl:value-of> VS <xsl:sequence> into a recursive call function containing <xsl:analyse-string>

2018-04-18 12:38:15
In your future postings to XSL-List please leave the “weird issue” out of the 
subject line. People often browse the subject lines in the archive and see only 
the beginning of the subjects - your question and the discussion it generates 
will be more easily found and more valuable in the future if the subject line 
JUST describes the subject. 

Thanks. 

— Tommie


On Apr 18, 2018, at 10:25 AM, Larnic Rick 
frederic(_dot_)lanic(_at_)gmail(_dot_)com 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:

Hello guys,
I detected a trouble issue around the difference of <xsl:sequence> and 
<xsl:value-of> of a string variable (xs:string type).
For me, the result of these both xsl element should be the same. But it seems 
not in fact. I don't understand why. Please help me :) !
The context of use is recursive call of an function containing 
<xsl:analyse-string>.

The result is different when <xsl:sequence> is used : some white spaces is 
inserted.
With <xsl:value-of> : no white spaces inserted => expected result.

Here's the xsl stylesheet : the trouble issue is in 
"xfe:replace-multiple-text-to-mix()" function, around the <xsl:otherwise>

<?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";
  xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl";
  xmlns:els="http://www.lefebvre-sarrut.eu/ns/els";
  xmlns:xfe="http://www.lefebvre-sarrut.eu/ns/xmlfirst/xmlEditor";
  exclude-result-prefixes="#all"
  version="3.0">

  <xd:doc scope="stylesheet">
    <xd:desc>
      <xd:p>Correct typos : manage french exposants</xd:p>
    </xd:desc>
  </xd:doc>

  <xsl:output encoding="UTF-8" indent="no" method="xml"/>

  <xd:doc>
    <xd:desc>Manage French Exposants</xd:desc>
  </xd:doc>
  <xsl:variable name="xfe:french-exposants-rules" 
as="element(els:replace-list)">
    <!-- for all rules : 2nd group is modified -->
    <replace-list xmlns="http://www.lefebvre-sarrut.eu/ns/els"; 
xml:space="preserve">
      <replace flags=";j">
        <pattern>([0-9]+)(er?|ère|nd|ème)</pattern>
        <element name="e">e</element>
      </replace>
      <replace flags=";j">
        <pattern>(.*n)([°o])( *[0-9]+)</pattern>
        <element name="e">o</element>
      </replace>
    </replace-list>
  </xsl:variable>

  <!-- ======================================================= -->
  <!-- INIT -->
  <!-- ======================================================= -->
  <xd:doc>
    <xd:desc>
      <xd:p>Correct exposants</xd:p>
    </xd:desc>
  </xd:doc>
  <xsl:template match="/">
    <xsl:variable name="step" select="." as="document-node()"/>
    <!-- single characters -->
    <xsl:variable name="step" as="document-node()">
      <xsl:document>
        <xsl:apply-templates select="$step" mode="xfe:french.exposants"/>
      </xsl:document>
    </xsl:variable>
    <xsl:sequence select="$step"/>
  </xsl:template>

  <!-- ======================================================= -->
  <!-- MAIN - mode="xfe:french.exposants" -->
  <!-- ======================================================= -->

  <xd:doc>
    <xd:desc>
      <xd:p>Manage exposant into the text()</xd:p>
    </xd:desc>
  </xd:doc>
  <xsl:template match="text()" mode="xfe:french.exposants">
    <xsl:variable name="string" select="." as="xs:string"/>
    <xsl:variable name="nsUri" select="namespace-uri(..)" as="xs:anyURI"/>
    <xsl:sequence select="xfe:replace-multiple-text-to-mix($string, 
$xfe:french-exposants-rules/els:replace, $nsUri)"/>
  </xsl:template>

  <xd:doc>
    <xd:desc>
      <xd:p>Replace text() to mix (element + text())</xd:p>
    </xd:desc>
    <xd:param name="string">text to parse</xd:param>
    <xd:param name="replace">sequence of &lt;els:replace&gt; 
elements</xd:param>
    <xd:param name="namespace">namespace of the new element</xd:param>
  </xd:doc>
  <xsl:function name="xfe:replace-multiple-text-to-mix" as="item()*">
    <xsl:param name="string" as="xs:string"/>
    <xsl:param name="replace" as="element(els:replace)*"/>
    <xsl:param name="namespace" as="xs:anyURI"/>
    <xsl:choose>
      <xsl:when test="count($replace) > 0">
        <xsl:analyze-string regex="{$replace[1]/els:pattern}" 
select="$string">
          <xsl:matching-substring>
            <xsl:variable name="e" as="element()">
              <xsl:element name="{$replace[1]/els:element/@name}" 
namespace="{$namespace}">
                <xsl:sequence select="$replace[1]/els:element/string()"/>
              </xsl:element>
            </xsl:variable>
            <xsl:sequence select="(regex-group(1), $e, 
if(normalize-space(regex-group(3)) != '') then(regex-group(3)) else())"/>     
       
          </xsl:matching-substring>
          <xsl:non-matching-substring>
            <xsl:sequence select="xfe:replace-multiple-text-to-mix(., 
$replace[position() > 1], $namespace)"/>
          </xsl:non-matching-substring>
        </xsl:analyze-string>
      </xsl:when>
      <xsl:otherwise><xsl:sequence select="$string"/></xsl:otherwise>
    </xsl:choose>
  </xsl:function>

  <xd:doc>
    <xd:desc>
      <xd:p>Default template mode="xfe:french.exposants"</xd:p>
    </xd:desc>
  </xd:doc>
  <xsl:template match="node() | @*" mode="xfe:french.exposants" priority="-1">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" mode="#current"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

And the Xspec XML source file is :
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <text> 1e n° 125 1er 10e </text>
  <text> no 125</text>
  <text> no </text>
  <text> 1er 10e </text>
  <text>1e </text>
  <text>2e </text>
  <text>3e </text>
  <text>4e </text>
  <text>5e </text>
  <text>6e </text>
  <text>7e </text>
  <text>8e </text>
  <text>9e </text>
  <text>10e </text>
  <text>1er,</text>
  <text>1e,</text>
  <text>2e,</text>
  <text>3e,</text>
  <text>4e,</text>
  <text>5e,</text>
  <text>6e,</text>
  <text>7e,</text>
  <text>8e,</text>
  <text>9e,</text>
  <text>10e,</text>
</root>

The results : (please see 1st and 4th line in particular)
- with "<xsl:otherwise><xsl:sequence select="$string"/></xsl:otherwise>" : 
(unexpected result)
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <text>  1<e>e</e> n<e>o</e> 125   1<e>e</e>  10<e>e</e> </text>
  <text> n<e>o</e> 125</text>
  <text> no </text>
  <text>  1<e>e</e>  10<e>e</e> </text>
  <text>1<e>e</e> </text>
  <text>2<e>e</e> </text>
  <text>3<e>e</e> </text>
  <text>4<e>e</e> </text>
  <text>5<e>e</e> </text>
  <text>6<e>e</e> </text>
  <text>7<e>e</e> </text>
  <text>8<e>e</e> </text>
  <text>9<e>e</e> </text>
  <text>10<e>e</e> </text>
  <text>1<e>e</e>,</text>
  <text>1<e>e</e>,</text>
  <text>2<e>e</e>,</text>
  <text>3<e>e</e>,</text>
  <text>4<e>e</e>,</text>
  <text>5<e>e</e>,</text>
  <text>6<e>e</e>,</text>
  <text>7<e>e</e>,</text>
  <text>8<e>e</e>,</text>
  <text>9<e>e</e>,</text>
  <text>10<e>e</e>,</text>
</root>

- with "<xsl:otherwise><xsl:value-of select="$string"/></xsl:otherwise>" 
(expected result)
<?xml version="1.0" encoding="UTF-8"?><root>
  <text> 1<e>e</e> n<e>o</e> 125 1<e>e</e> 10<e>e</e> </text>
  <text> n<e>o</e> 125</text>
  <text> no </text>
  <text> 1<e>e</e> 10<e>e</e> </text>
  <text>1<e>e</e> </text>
  <text>2<e>e</e> </text>
  <text>3<e>e</e> </text>
  <text>4<e>e</e> </text>
  <text>5<e>e</e> </text>
  <text>6<e>e</e> </text>
  <text>7<e>e</e> </text>
  <text>8<e>e</e> </text>
  <text>9<e>e</e> </text>
  <text>10<e>e</e> </text>
  <text>1<e>e</e>,</text>
  <text>1<e>e</e>,</text>
  <text>2<e>e</e>,</text>
  <text>3<e>e</e>,</text>
  <text>4<e>e</e>,</text>
  <text>5<e>e</e>,</text>
  <text>6<e>e</e>,</text>
  <text>7<e>e</e>,</text>
  <text>8<e>e</e>,</text>
  <text>9<e>e</e>,</text>
  <text>10<e>e</e>,</text>
</root>

Direct test of this function with XSpec :
for each case, here's the result I have (the source is the 1st line) :
- <xsl:sequence> use : (' ', '1', xs:anyAtomicType('e'), ' n', 
xs:anyAtomicType('o'), ' 125', ' ', '1', xs:anyAtomicType('e'), ' ', '10', 
xs:anyAtomicType('e'), ' ')
- <xsl:value-of> use : (xs:anyAtomicType(' '), '1', xs:anyAtomicType('e'), ' 
n', xs:anyAtomicType('o'), ' 125', xs:anyAtomicType(' '), '1', 
xs:anyAtomicType('e'), xs:anyAtomicType(' '), '10', xs:anyAtomicType('e'), 
xs:anyAtomicType(' '))
XPath /n

If you agree, I could add the xspec file I use for this.

Please, could you explain me why there is this difference of white spaces ?
Thanks in advance,
Fred
XSL-List info and archive
EasyUnsubscribe (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>