Search code examples
javascriptxmlxsltrdf

xsl adds empty space?


I have a sparql-results XML file. I get it from RD4J-Rest API. When I open the file in Notepad++, it is as expected: (Sample)

<result>
        <binding name='ilAbk'>
            <literal>[A_2mim]Ll</literal>
        </binding>
</result>

Now I am using an XSL template to format the output:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:res="http://www.w3.org/2005/sparql-results#">
<xsl:output method="xml" encoding="UTF-8" />

<xsl:template name="vb-result">
  <table id="main">
    <xsl:for-each select="res:results/res:result">
      <tr id="{generate-id()}">
        <xsl:apply-templates select="."/>
      </tr>
    </xsl:for-each>
  </table>
</xsl:template>

<xsl:template match="res:result">
  <xsl:variable name="current" select="."/>
  <xsl:for-each select="/res:sparql/res:head/res:variable">
    <xsl:variable name="name" select="@name"/>
    <td>
      <xsl:apply-templates select="$current/res:binding[@name=$name]"/>
    </td>
  </xsl:for-each>
</xsl:template>

<xsl:template match="res:sparql">
  <xsl:call-template name="vb-result" />
</xsl:template>

</xsl:stylesheet>

In the final Table the [A_2mim]Ll has the same characters count (9). But when I access it with JavaScript and display it in the console, it get's ten additional empty characters. Here is the JavaScript part:

function addRowHandlers() {
    var table = document.getElementById("main");
    var rows = table.getElementsByTagName("tr");
    for (i = 0; i < rows.length; i++) {
        var currentRow = table.rows[i];
        var createClickHandler = 
        function(row) 
        {
            return function() { 
                var cell = row.getElementsByTagName("td")[0];
                var text = cell.innerHTML;
                var rid = row.getAttribute("id");
                console.log(text.length);
            };
        };

    currentRow.onclick = createClickHandler(currentRow);
    }
}

Because I would like to use this name for the next query, I need to get rid of these characters. I know that I could cut it, but I was wondering if somebody would have an idea where these characters come from. It looks strange in the console - that's why I checked it with the .length.

Thanks for your time.


Solution

  • It is because of this line here where you select the binding element

     <xsl:apply-templates select="$current/res:binding[@name=$name]"/>
    

    The issue is you do not have a template matching res:binding or any of its descendants. This means XSLT will use its built-in templates, which ultimately select all descendent text nodes. This include the whitespace nodes, before and after the literal element that is used for indentation. It is this whitespace that is probably given you your confusing results.

    There are a number of ways to solve it. Firstly, you can add a xsl:strip-space command after the xsl:output command, to tell XSLT to ignore whitespace only nodes

     <xsl:strip-space elements="*" />
    

    Alternatively, you can be more specific with you xsl:apply-templates and target the literal element directly.

     <xsl:apply-templates select="$current/res:binding[@name=$name]/res:literal"/>