2
votes

I'm getting this error while I try to put XPath into match. What do I do wrong? This is my XML example

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<ROOT>
  <DOCUMENT name="HLSSD">
    <TAG1 name="t1">
      text0
      <ELEM1 id="el1">
      text1
      </ELEM1>
      <MYELEMENT/>
      <ELEM2 id="el2">
      text2
        <ELEM2 id="el3">
        text3
        </ELEM2>
        <MYELEMENT/>
        <ELEM1 id="el4">
        text4
        </ELEM1>
        <MYELEMENT/>
        text4.5
        <ELEM1 id="el5">
        text5
        </ELEM1>
        <TAG3 name="t2"/>
        text5.6
        <ELEM2 id="el6">
        text6
        </ELEM2>
      </ELEM2>
      </TAG1>
    <TAG1 name="t3">
      <ELEM1 id="el7">
      text7
      </ELEM1>
      <ELEM2 id="el8">
        text3
        </ELEM2>
        <MYELEMENT/>
        <ELEM1 id="el9">
        text4
        </ELEM1>
        <MYELEMENT/>
        text4.5
        <ELEM1 id="el10">
        text5
        </ELEM1>
        <TAG3 name="t4"/>
        text5.6
        <ELEM2 id="el11">
        text6
      </ELEM2>
    </TAG1>
    <TAG2 name="t4">
    </TAG2>
    <TAG2 name="t5">
    </TAG2>
    <TAG1 name="t6">
    </TAG1>
  </DOCUMENT>
</ROOT>

Here is my XSL code:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
 <html>
 <body><xsl:apply-templates/></body>
 </html>
 </xsl:template>
<xsl:template match="DOCUMENT">
  <div>
  <h1><xsl:value-of select="@name" /></h1>
  <xsl:apply-templates/>
  </div>
</xsl:template>
<xsl:template match="TAG1|TAG2|TAG3">
 <div>
  <h1><xsl:value-of select="name()" /></h1>
  <p><xsl:value-of select="@name" /></p>
  <pre><xsl:apply-templates/></pre>
  </div>
</xsl:template>
<xsl:template match="ELEM1|ELEM2">
    <p>(<xsl:apply-templates/>)</p>
</xsl:template>
<xsl:template match="MYELEMENT/following-sibling::*[count(.|(TAG1|TAG2|TAG3|MYELEMENT)/preceding-sibling::*)=count((TAG1|TAG2|TAG3|MYELEMENT)/preceding-sibling::*)]">
<div>
  <h1><xsl:value-of select="name()" /></h1>
  <p><xsl:apply-templates/></p>
</div>
</xsl:template>
</xsl:stylesheet> 

What I want is to find MYELEMENT and everything after at same level until first (one) of TAG1 or TAG2 or TAG3 or MYELEMENT or to be concrete I want to wrap with div tag every elements from MYELEMENT to first of TAG1 or TAG2 or TAG3 or MYELEMENT at same level or the end of parent element.

Output should be this:

<html>
<body>
<div>
 <h1>DocName</h1>
    <div>
     <h1>TAG1</h1>
     <p>t1</p>
     <pre>
      text0
      <p>(
      text1
      )</p>
      **<DIV>**
      **<H1>MYELEMENT</H1>**
      <p>(
      text2
        <p>(
        text3
        )</p>
        **<DIV>**
        **<H1>MYELEMENT</H1>**
        <p>(
        text4
        )</p>
        **</DIV>**
        **<DIV>**
        <H1>MYELEMENT</H1>
        text4.5
        <p>(
        text5
        )</p>
        **</DIV>**
        <div>
         <h1>TAG3</h1>
         <p>t2</p>
         <pre></pre>
        </div>
        text5.6
        <p>(
        text6
        )</p>
      )</p>
      **</DIV>**
      </pre>
    </div>
    <div>
     <h1>TAG1</h1>
     <p>t3</p>
     <pre>
      <p>(
      text7
      )</p>
      <p>(
        text3
        )</p>
        **<DIV>**
        **<H1>MYELEMENT</H1>**
        <p>(
        text4
        )</p>
        **</DIV>**
        **<DIV>**
        **<H1>MYELEMENT</H1>**
        text4.5
        <p>(
        text5
        )</p>
        **</DIV>**
        <div>
         <h1>TAG3</h1>
         <p>t4</p>
         <pre></pre>
        </div>
        text5.6
        <p>(
        text6
      )</p>
    </pre>
    </div>
    <div>
     <h1>TAG2</h1>
     <p>t5</p>
     <pre>
    </pre>
    </div>
    <div>
     <h1>TAG2</h1>
     <p>t6</p>
     <pre>
    </pre>
    </div>
    <div>
     <h1>TAG1</h1>
     <p>t7</p>
     <pre>
    </pre>
    </div>
</div>
</body>
</html>
1
As for the cause of the error, see w3.org/TR/xslt#patterns about XSLT patterns: "A location path pattern is a location path whose steps all use only the child or attribute axes". So you can't use a pattern like you have with a step using following-sibling::*.Martin Honnen
Ok, but this doesn't work too :( <xsl:template match="MYELEMENT"> <xsl:for-each select="./following-sibling::*[count(.|(TAG1|TAG2|TAG3|MYELEMENT)/preceding-sibling::*)=count((TAG1|TAG2|TAG3|MYELEMENT)/preceding-sibling::*)]">zelenooq

1 Answers

0
votes

You can change your match path to a valid path with the same semantic meaning like this:

<xsl:template match="*[preceding-sibling::MYELEMENT and 
  count(.|(TAG1|TAG2|TAG3|MYELEMENT)/preceding-sibling::*) = 
  count((TAG1|TAG2|TAG3|MYELEMENT)/preceding-sibling::*)]">