Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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 仅选择以下某些同级节点_Xml_Xslt_Xpath - Fatal编程技术网

Xml 仅选择以下某些同级节点

Xml 仅选择以下某些同级节点,xml,xslt,xpath,Xml,Xslt,Xpath,我有以下XML: <root> <table>Table 1</table> <foot>1.1</foot> <foot>2.2</foot> <p>...</p> <p>...</p> <table>Table X</table> <foot>M.1</foot> <foot>M.2</foot&

我有以下XML:

<root>
<table>Table 1</table>
<foot>1.1</foot>
<foot>2.2</foot>
<p>...</p>
<p>...</p>
<table>Table X</table>
<foot>M.1</foot>
<foot>M.2</foot>
<p>...</p>
<p>...</p>
<table>Table 132</table>
<foot>A.A.E</foot>
<foot>234</foot>
<p>...</p>
<p>...</p>
</root>

表1
1.1
2.2

表十 M.1 M.2

表132 A.A.E 234

我想将其转换为:

<root>
<table>
 <text>Table 1</text>
 <foot>1.1</foot>
 <foot>2.2</foot>
</table>
<p>...</p>
<p>...</p>
<table>
 <text>Table X</text>
 <foot>M.1</foot>
 <foot>M.2</foot>
</table>
<p>...</p>
<p>...</p>
<table>
 <text>Table 132</text>
 <foot>A.A.E</foot>
 <foot>234</foot>
</table>
<p>...</p>
<p>...</p>
</root>

表1
1.1
2.2

表十 M.1 M.2

表132 A.A.E 234

我有以下XSL代码:

<xsl:template match="table">
 <xsl:element name="table">
  <xsl:element name="text">
   <xsl:apply-templates />
  </xsl:element>
  <xsl:for-each select="following-sibling::foot">
   <xsl:element name="foot">
    <xsl:apply-templates />
   </xsl:element>
  </xsl:for-each>
 </xsl:element>

其输出为:

<root>
<table>
 <text>Table 1</text>
 <foot>1.1</foot>
 <foot>2.2</foot>
 <foot>M.1</foot>
 <foot>M.2</foot>
 <foot>A.A.E</foot>
 <foot>234</foot>
</table>
<p>...</p>
<p>...</p>
<table>
 <text>Table X</text>
 <foot>M.1</foot>
 <foot>M.2</foot>
 <foot>A.A.E</foot>
 <foot>234</foot>
</table>
<p>...</p>
<p>...</p>
<table>
 <text>Table 132</text>
 <foot>A.A.E</foot>
 <foot>234</foot>
</table>
<p>...</p>
<p>...</p>
</root>

表1
1.1
2.2
M.1
M.2
A.A.E
234

表十 M.1 M.2 A.A.E 234

表132 A.A.E 234


如果紧跟在
元素之后的
n
foot
元素,则如何仅选择紧跟在关闭
元素之后的
foot
元素。在此方面的任何帮助都将不胜感激

最干净的方法是使用XSL键。(此答案中的解决方案适用于所有XSLT版本。)


使用前一个
的唯一ID(请参阅)索引文档中的所有
元素

然后,
在相同唯一ID的帮助下选择属于每个
元素


这方面的功能等同于:

<xsl:template match="table">
    <xsl:copy>
        <text><xsl:apply-templates select="@*|node()"/></text>
        <xsl:copy-of select="following-sibling::foot[
            generate-id(preceding-sibling::table[1]) = generate-id(current())
        ]" />
    </xsl:copy>
</xsl:template>

在此变体中,不需要XSL密钥。这两种情况的结果都是:

<root>
   <table>
      <text>Table 1</text>
      <foot>1.1</foot>
      <foot>2.2</foot>
   </table>
   <p>...</p>
   <p>...</p>
   <table>
      <text>Table X</text>
      <foot>M.1</foot>
      <foot>M.2</foot>
   </table>
   <p>...</p>
   <p>...</p>
   <table>
      <text>Table 132</text>
      <foot>A.A.E</foot>
      <foot>234</foot>
   </table>
   <p>...</p>
   <p>...</p>
</root>

表1
1.1
2.2

表十 M.1 M.2

表132 A.A.E 234


注:

  • 不要使用
    。您只需编写
    <代码>用于未预先确定元素名称的情况
  • 避免
    。在大多数情况下,与
    一起工作更为优越

最干净的方法是使用XSL键。(此答案中的解决方案适用于所有XSLT版本。)


使用前一个
的唯一ID(请参阅)索引文档中的所有
元素

然后,
在相同唯一ID的帮助下选择属于每个
元素


这方面的功能等同于:

<xsl:template match="table">
    <xsl:copy>
        <text><xsl:apply-templates select="@*|node()"/></text>
        <xsl:copy-of select="following-sibling::foot[
            generate-id(preceding-sibling::table[1]) = generate-id(current())
        ]" />
    </xsl:copy>
</xsl:template>

在此变体中,不需要XSL密钥。这两种情况的结果都是:

<root>
   <table>
      <text>Table 1</text>
      <foot>1.1</foot>
      <foot>2.2</foot>
   </table>
   <p>...</p>
   <p>...</p>
   <table>
      <text>Table X</text>
      <foot>M.1</foot>
      <foot>M.2</foot>
   </table>
   <p>...</p>
   <p>...</p>
   <table>
      <text>Table 132</text>
      <foot>A.A.E</foot>
      <foot>234</foot>
   </table>
   <p>...</p>
   <p>...</p>
</root>

表1
1.1
2.2

表十 M.1 M.2

表132 A.A.E 234


注:

  • 不要使用
    。您只需编写
    <代码>用于未预先确定元素名称的情况
  • 避免
    。在大多数情况下,与
    一起工作更为优越

基本上,这是一个分组问题。如果您使用的是XSLT 2.0,则可以利用其内置的分组功能:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each-group select="*" group-starting-with="table">
            <table>
                <text>
                    <xsl:value-of select="."/>
                </text>
                <xsl:copy-of select="current-group()[self::foot]"/>
            </table>
            <xsl:copy-of select="current-group()[not(self::table or self::foot)]"/>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

基本上,这是一个分组问题。如果您使用的是XSLT 2.0,则可以利用其内置的分组功能:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each-group select="*" group-starting-with="table">
            <table>
                <text>
                    <xsl:value-of select="."/>
                </text>
                <xsl:copy-of select="current-group()[self::foot]"/>
            </table>
            <xsl:copy-of select="current-group()[not(self::table or self::foot)]"/>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>


您能使用XSLT 2.0吗?对不起。XSLT2.0还可以。我应该指定它。你能使用XSLT2.0吗?对不起。XSLT2.0还可以。我应该指定它。对于XSLT 2.0环境,@michael.hor257k提供的解决方案当然更好。对于XSLT 2.0环境,@michael.hor257k提供的解决方案当然更好。