4

Name of the XSLT change element - previous-brother misunderstood

 3 years ago
source link: https://www.codesd.com/item/name-of-the-xslt-change-element-previous-brother-misunderstood.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Name of the XSLT change element - previous-brother misunderstood

advertisements

I wanna change specific td to th in xhtml file if next element's class is 'xxx' and then delete this elements (with class 'xxx'), but preceding-sibling is wrong in template so I must miss something:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:x="http://www.w3.org/1999/xhtml">
    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="//x:tr[@class='xxx']/preceding-sibling::x:tr/td">
      <th>
          <xsl:apply-templates select="@* | node()"/>
      </th>
    </xsl:template>
    <xsl:template match="//x:tr[@class='xxx']"/>
</xsl:stylesheet>

EDIT: sample document:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="cs-CZ" xml:lang="cs-CZ">
<head>
    <title>test</title>
    <meta charset="UTF-8"/>
    <link rel="stylesheet" type="text/css" href="xxx.css"/>
</head>
<body>
    <table>
        <tr>
            <td>1</td>
            <td>2</td>
            <td>3</td>
        </tr>
        <tr class="xxx">
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>a</td>
            <td>b</td>
            <td>c</td>
        </tr>
        <tr>
            <td>error row to remove if present</td>
        </tr>
    </table>
</body>
</html>

What I want is first row of table as th and remove last error row if present and keep HTML5 doctype:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="cs-CZ" xml:lang="cs-CZ">
<head>
    <title>test</title>
    <meta charset="UTF-8"/>
    <link rel="stylesheet" type="text/css" href="xxx.css"/>
</head>
<body>
    <table>
        <tr>
            <th>1</th>
            <th>2</th>
            <th>3</th>
        </tr>
        <tr>
            <td>a</td>
            <td>b</td>
            <td>c</td>
        </tr>
    </table>
</body>
</html>

I get (with <xsl:template match="//x:tr[following-sibling::x:tr[1]/@class='xxx']/x:td"> which is now valid in XSLT document):

<?xml version='1.0' encoding='UTF-8'?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" lang="cs-CZ" xml:lang="cs-CZ">
<head>
    <title>test</title>
    <meta charset="UTF-8"/>
    <link rel="stylesheet" type="text/css" href="xxx.css"/>
</head>
<body>
    <table>
        <tr>
            <th xmlns="" xmlns:x="http://www.w3.org/1999/xhtml">1</th>
            <th xmlns="" xmlns:x="http://www.w3.org/1999/xhtml">2</th>
            <th xmlns="" xmlns:x="http://www.w3.org/1999/xhtml">3</th>
        </tr>

        <tr>
            <td>a</td>
            <td>b</td>
            <td>c</td>
        </tr>
        <tr>
            <td>error row to remove if present</td>
        </tr>
    </table>
</body>

So there is no doctype and at th cells are namespaces which would not be there. I don't know howto remove wrong row (it should be always last row).


If you want to create new th elements in the XHTML namespace then you need to add it to the stylesheet:

<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:x="http://www.w3.org/1999/xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    exclude-result-prefixes="x">

    <xsl:output method="xml" doctype-system="about:legacy-compat"/>

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

    <xsl:template match="x:tr[following-sibling::x:tr[1][@class = 'xxx']]/x:td">
        <th>
            <xsl:apply-templates select="@* | node()"/>
        </th>
    </xsl:template>

    <xsl:template match="x:tr[@class = 'xxx'] | x:tr[last()]"/>

</xsl:stylesheet>

As for keeping the DOCTYPE, you would need to create a new one and at least in XSLT 1.0 (which was finalized in 1999 some 15 years before HTML5) all you can do is use <xsl:output method="xml" doctype-system="about:legacy-compat"/> to output

<!DOCTYPE html
  SYSTEM "about:legacy-compat">




About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK