Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 使用XSLT/XPath查找文档中的上一个/下一个元素_Xml_Xslt_Xpath - Fatal编程技术网

Xml 使用XSLT/XPath查找文档中的上一个/下一个元素

Xml 使用XSLT/XPath查找文档中的上一个/下一个元素,xml,xslt,xpath,Xml,Xslt,Xpath,我想不出一种简单而优雅的方法来使用XPath或简单的XSLT模板在XML文档中查找“上一个”和“下一个”元素。下面是一个示例XML文档(在实际文档中,@id的排序不会这么简单) 前置::轴的问题是排除了祖先,即节[id=2]不是节[id=3]的前置节点 同样地,following::轴排除子体,即节[id=3]不是节[id=2]的后续节点 因此,我如何生成“上一个”和“下一个”元素,例如从这些模板生成: <xsl:template match="section" mode="prev"&g

我想不出一种简单而优雅的方法来使用XPath或简单的XSLT模板在XML文档中查找“上一个”和“下一个”元素。下面是一个示例XML文档(在实际文档中,
@id
的排序不会这么简单)

前置::
轴的问题是排除了祖先,即
节[id=2]
不是
节[id=3]
的前置节点

同样地,
following::
轴排除子体,即
节[id=3]
不是
节[id=2]
的后续节点

因此,我如何生成“上一个”和“下一个”元素,例如从这些模板生成:

<xsl:template match="section" mode="prev">
  <xsl:value-of select="... what to put here ..."/>
</xsl:template>

<xsl:template match="section" mode="next">
  <xsl:value-of select="... what to put here ..."/>
</xsl:template>


注意,这是一个类似但不相同的问题:。这些XPath构造真的让我难以理解,有时…

这里有一个样式表,它将Nicholas的建议与union结合在一起,然后将
last()
用于上一项,将第一项用于下一项:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

  <xsl:output method="html" indent="yes"/>

  <xsl:template match="manual">
    <table>
      <thead>
        <tr>
          <th>Selected section</th>
          <th>Previous section</th>
          <th>Next section</th>
        </tr>
      </thead>
      <tbody>
        <xsl:apply-templates select="descendant::section"/>
      </tbody>
    </table>
  </xsl:template>

  <xsl:template match="section">
    <tr>
      <td>
        <xsl:value-of select="@id"/>
      </td>
      <xsl:apply-templates select="." mode="prev"/>
      <xsl:apply-templates select="." mode="next"/>
    </tr>
  </xsl:template>

  <xsl:template match="section" mode="prev">
    <td>
      <xsl:value-of select="(preceding::section | ancestor::section)[last()]/@id"/>
    </td>
  </xsl:template>

  <xsl:template match="section" mode="next">
    <td>
      <xsl:value-of select="(following::section | descendant::section)[1]/@id"/>
    </td>
  </xsl:template>

</xsl:stylesheet>

选定部分
上一节
下一节
使用示例输入Saxon 6.5.5输出

<table>
   <thead>
      <tr>
         <th>Selected section</th>
         <th>Previous section</th>
         <th>Next section</th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>1</td>
         <td></td>
         <td>2</td>
      </tr>
      <tr>
         <td>2</td>
         <td>1</td>
         <td>3</td>
      </tr>
      <tr>
         <td>3</td>
         <td>1</td>
         <td>4</td>
      </tr>
      <tr>
         <td>4</td>
         <td>1</td>
         <td>5</td>
      </tr>
      <tr>
         <td>5</td>
         <td>1</td>
         <td>6</td>
      </tr>
      <tr>
         <td>6</td>
         <td>1</td>
         <td>7</td>
      </tr>
      <tr>
         <td>7</td>
         <td>1</td>
         <td>8</td>
      </tr>
      <tr>
         <td>8</td>
         <td>1</td>
         <td>9</td>
      </tr>
      <tr>
         <td>9</td>
         <td>1</td>
         <td>10</td>
      </tr>
      <tr>
         <td>10</td>
         <td>1</td>
         <td>11</td>
      </tr>
      <tr>
         <td>11</td>
         <td>1</td>
         <td>12</td>
      </tr>
      <tr>
         <td>12</td>
         <td>1</td>
         <td></td>
      </tr>
   </tbody>
</table>

选定部分
上一节
下一节
1.
2.
2.
1.
3.
3.
1.
4.
4.
1.
5.
5.
1.
6.
6.
1.
7.
7.
1.
8.
8.
1.
9
9
1.
10
10
1.
11
11
1.
12
12
1.

这是一个样式表,它将尼古拉斯的建议与工会结合在一起,然后将
last()
用于上一项,将第一项用于下一项:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

  <xsl:output method="html" indent="yes"/>

  <xsl:template match="manual">
    <table>
      <thead>
        <tr>
          <th>Selected section</th>
          <th>Previous section</th>
          <th>Next section</th>
        </tr>
      </thead>
      <tbody>
        <xsl:apply-templates select="descendant::section"/>
      </tbody>
    </table>
  </xsl:template>

  <xsl:template match="section">
    <tr>
      <td>
        <xsl:value-of select="@id"/>
      </td>
      <xsl:apply-templates select="." mode="prev"/>
      <xsl:apply-templates select="." mode="next"/>
    </tr>
  </xsl:template>

  <xsl:template match="section" mode="prev">
    <td>
      <xsl:value-of select="(preceding::section | ancestor::section)[last()]/@id"/>
    </td>
  </xsl:template>

  <xsl:template match="section" mode="next">
    <td>
      <xsl:value-of select="(following::section | descendant::section)[1]/@id"/>
    </td>
  </xsl:template>

</xsl:stylesheet>

选定部分
上一节
下一节
使用示例输入Saxon 6.5.5输出

<table>
   <thead>
      <tr>
         <th>Selected section</th>
         <th>Previous section</th>
         <th>Next section</th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>1</td>
         <td></td>
         <td>2</td>
      </tr>
      <tr>
         <td>2</td>
         <td>1</td>
         <td>3</td>
      </tr>
      <tr>
         <td>3</td>
         <td>1</td>
         <td>4</td>
      </tr>
      <tr>
         <td>4</td>
         <td>1</td>
         <td>5</td>
      </tr>
      <tr>
         <td>5</td>
         <td>1</td>
         <td>6</td>
      </tr>
      <tr>
         <td>6</td>
         <td>1</td>
         <td>7</td>
      </tr>
      <tr>
         <td>7</td>
         <td>1</td>
         <td>8</td>
      </tr>
      <tr>
         <td>8</td>
         <td>1</td>
         <td>9</td>
      </tr>
      <tr>
         <td>9</td>
         <td>1</td>
         <td>10</td>
      </tr>
      <tr>
         <td>10</td>
         <td>1</td>
         <td>11</td>
      </tr>
      <tr>
         <td>11</td>
         <td>1</td>
         <td>12</td>
      </tr>
      <tr>
         <td>12</td>
         <td>1</td>
         <td></td>
      </tr>
   </tbody>
</table>

选定部分
上一节
下一节
1.
2.
2.
1.
3.
3.
1.
4.
4.
1.
5.
5.
1.
6.
6.
1.
7.
7.
1.
8.
8.
1.
9
9
1.
10
10
1.
11
11
1.
12
12
1.
一个“不那么优雅”的实现是这样的(选择
@id
而不是整个节点)


一个“不那么优雅”的实现是这样的(选择
@id
而不是整个节点)



将它们与|结合在一起,然后选择first@Nicholas:联合什么<代码>前面的::和祖先:?这对
@id=6
不起作用,我想前面的部分应该是5?@Nicholas,我错了。见马丁的答案。谢谢大家!将它们与|合并并选择first@Nicholas:联合什么<代码>前面的::和祖先:?这对
@id=6
不起作用,我想前面的部分应该是5?@Nicholas,我错了。见马丁的答案。谢谢大家!真的很管用!很好,所以我误解了
前面::
后面::
的概念。谢谢!真的很管用!很好,所以我误解了
前面::
后面::
的概念。谢谢!
<xsl:template match="section" mode="prev-id">
  <xsl:variable name="id" select="@id"/>

  <xsl:variable name="position">
    <xsl:for-each select="//section">
      <xsl:if test="@id = $id">
        <xsl:value-of select="position()"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:for-each select="//section">
    <xsl:if test="position() = $position - 1">
      <xsl:value-of select="@id"/>
    </xsl:if>
  </xsl:for-each>
</xsl:template>

<xsl:template match="section" mode="next-id">
  <xsl:variable name="id" select="@id"/>

  <xsl:variable name="position">
    <xsl:for-each select="//section">
      <xsl:if test="@id = $id">
        <xsl:value-of select="position()"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:for-each select="//section">
    <xsl:if test="position() = $position + 1">
      <xsl:value-of select="@id"/>
    </xsl:if>
  </xsl:for-each>
</xsl:template>