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 如何获取下面的下一个直接值::node()<;w:tbl>;使用xslt2.0的上下文节点的元素?_Xml_Xslt_Xpath_Xslt 2.0_Xpath 2.0 - Fatal编程技术网

Xml 如何获取下面的下一个直接值::node()<;w:tbl>;使用xslt2.0的上下文节点的元素?

Xml 如何获取下面的下一个直接值::node()<;w:tbl>;使用xslt2.0的上下文节点的元素?,xml,xslt,xpath,xslt-2.0,xpath-2.0,Xml,Xslt,Xpath,Xslt 2.0,Xpath 2.0,我想通过使用xslt 2.0将一种xml格式转换为另一种xml格式。现在,我想获取上下文节点的下一个紧挨着的::node()元素 这是我的xml文档: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"

我想通过使用xslt 2.0将一种xml格式转换为另一种xml格式。现在,我想获取上下文节点的下一个紧挨着的::node()元素

这是我的xml文档:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
                    xmlns:v="urn:schemas-microsoft-com:vml">
        <w:body>
      <w:p>para1</w:p>   <!-- assume this as context node  -->
      <w:tbl>table data 1</w:tbl>
      <w:tbl>table data 2</w:tbl>
      <w:p>para2</w:p>
      <w:tbl>table data 3</w:tbl>
      <w:tbl>table data 4</w:tbl>
      <w:tbl>table data 5</w:tbl>
      <w:tbl>table data 6</w:tbl>
      <w:p>para3</w:p>
   </w:body>
  </w:document>

帕拉1
表数据1
表数据2
帕拉2
表数据3
表数据4
表数据5
表数据6
帕拉3
因此,根据上述xml文件中提到的上下文节点,我只想选择表数据1和表数据2

例如,如果我的上下文节点是para2,那么我只想选择表数据3、表数据4、表数据5和表数据6

因此,我编写了这样的xslt

<xsl:for-each select="following::node()/self::w:tbl">
     <xsl:choose>
         <xsl:when test="self::w:tbl">
             <xsl:apply-templates select="self::w:tbl"></xsl:apply-templates>
          </xsl:when>                                             
     </xsl:choose>                                         
</xsl:for-each>

但它产生了错误的结果


请引导我离开这个问题…

假设您位于w:p元素上,您可以得到以下所有w:tbl兄弟姐妹,其最前面的w:p是当前元素

<xsl:apply-templates 
   select="following-sibling::w:tbl
     [generate-id(preceding-sibling::w:p[1]) = generate-id(current())]" />

这可以通过使用xsl:key来稍微整理一下。如果要定义以下键:

<xsl:key name="tbl" match="w:tbl" use="generate-id(preceding-sibling::w:p[1])" />

然后您可以得到如下w:tbl元素,如下所示:

<xsl:apply-templates select="key('tbl', generate-id())" />

例如,给定以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
   xmlns:v="urn:schemas-microsoft-com:vml" exclude-result-prefixes="w v">
   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="tbl" match="w:tbl" use="generate-id(preceding-sibling::w:p[1])" />

   <xsl:template match="w:body">
      <xsl:apply-templates select="w:p[1]" />
   </xsl:template>

   <xsl:template match="w:p">
      <xsl:apply-templates select="key('tbl', generate-id())" />
   </xsl:template>   

   <xsl:template match="w:tbl">
      <table><xsl:value-of select="." /></table>
   </xsl:template>
</xsl:stylesheet>

应用于示例XML时,将输出以下内容:

<table>table data 1</table>
<table>table data 2</table>
表数据1
表数据2

请注意,这是一个XSLT1.0解决方案。可能还有其他方法只能在XSLT2.0中使用。

假设您位于w:p元素上,您可以得到以下所有w:tbl同级元素,它们的前一个w:p是当前元素

<xsl:apply-templates 
   select="following-sibling::w:tbl
     [generate-id(preceding-sibling::w:p[1]) = generate-id(current())]" />

这可以通过使用xsl:key来稍微整理一下。如果要定义以下键:

<xsl:key name="tbl" match="w:tbl" use="generate-id(preceding-sibling::w:p[1])" />

然后您可以得到如下w:tbl元素,如下所示:

<xsl:apply-templates select="key('tbl', generate-id())" />

例如,给定以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
   xmlns:v="urn:schemas-microsoft-com:vml" exclude-result-prefixes="w v">
   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="tbl" match="w:tbl" use="generate-id(preceding-sibling::w:p[1])" />

   <xsl:template match="w:body">
      <xsl:apply-templates select="w:p[1]" />
   </xsl:template>

   <xsl:template match="w:p">
      <xsl:apply-templates select="key('tbl', generate-id())" />
   </xsl:template>   

   <xsl:template match="w:tbl">
      <table><xsl:value-of select="." /></table>
   </xsl:template>
</xsl:stylesheet>

应用于示例XML时,将输出以下内容:

<table>table data 1</table>
<table>table data 2</table>
表数据1
表数据2

请注意,这是一个XSLT1.0解决方案。可能还有其他方法只能在XSLT2.0中使用。

以下是一个可能有用的函数:

<xsl:function name="f:adjacently-following" as="element()*">
  <xsl:param name="start" as="element()"/>
  <xsl:param name="elementName" as="xs:QName"/>
  <xsl:variable name="next" select="$start/following-sibling::*[1]"/>
  <xsl:if test="node-name($next) = $elementName">
      <xsl:sequence select="$next, f:adjacently-following($next, $elementName)"/>
  </xsl:if>
</xsl:function>


然后可以调用
f:following(,xs:QName('w:tbl'))
下面是一个可能有用的函数:

<xsl:function name="f:adjacently-following" as="element()*">
  <xsl:param name="start" as="element()"/>
  <xsl:param name="elementName" as="xs:QName"/>
  <xsl:variable name="next" select="$start/following-sibling::*[1]"/>
  <xsl:if test="node-name($next) = $elementName">
      <xsl:sequence select="$next, f:adjacently-following($next, $elementName)"/>
  </xsl:if>
</xsl:function>


然后可以调用
f:following(,xs:QName('w:tbl'))
这个XSLT2.0样式表

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
  xmlns:v="urn:schemas-microsoft-com:vml"
  exclude-result-prefixes="xsl w v">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
 <root>
   <xsl:for-each-group select="w:document/w:body/(w:p|w:tbl)" group-starting-with="w:p" >
    <p>
      <xsl:apply-templates select="current-group()" />
    </p>
   </xsl:for-each-group>
 </root>
</xsl:template>

<xsl:template match="w:tbl">
  <table>
    <xsl:value-of select="." />
  </table>
</xsl:template>

</xsl:stylesheet>


…应用于此输入文档时

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:v="urn:schemas-microsoft-com:vml">
    <w:body>
        <w:p>para1</w:p>
        <!-- assume this as context node -->
        <w:tbl>table data 1</w:tbl>
        <w:tbl>table data 2</w:tbl>
        <w:p>para2</w:p>
        <w:tbl>table data 3</w:tbl>
        <w:tbl>table data 4</w:tbl>
        <w:tbl>table data 5</w:tbl>
        <w:tbl>table data 6</w:tbl>
        <w:p>para3</w:p>
    </w:body>
</w:document>

帕拉1
表数据1
表数据2
帕拉2
表数据3
表数据4
表数据5
表数据6
帕拉3
…产生

<root>
   <p>para1<table>table data 1</table>
      <table>table data 2</table>
   </p>
   <p>para2<table>table data 3</table>
      <table>table data 4</table>
      <table>table data 5</table>
      <table>table data 6</table>
   </p>
   <p>para3</p>
</root>

平行表数据1
表数据2

准表数据3 表数据4 表数据5 表数据6

帕拉3


此XSLT 2.0样式表

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
  xmlns:v="urn:schemas-microsoft-com:vml"
  exclude-result-prefixes="xsl w v">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
 <root>
   <xsl:for-each-group select="w:document/w:body/(w:p|w:tbl)" group-starting-with="w:p" >
    <p>
      <xsl:apply-templates select="current-group()" />
    </p>
   </xsl:for-each-group>
 </root>
</xsl:template>

<xsl:template match="w:tbl">
  <table>
    <xsl:value-of select="." />
  </table>
</xsl:template>

</xsl:stylesheet>


…应用于此输入文档时

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:v="urn:schemas-microsoft-com:vml">
    <w:body>
        <w:p>para1</w:p>
        <!-- assume this as context node -->
        <w:tbl>table data 1</w:tbl>
        <w:tbl>table data 2</w:tbl>
        <w:p>para2</w:p>
        <w:tbl>table data 3</w:tbl>
        <w:tbl>table data 4</w:tbl>
        <w:tbl>table data 5</w:tbl>
        <w:tbl>table data 6</w:tbl>
        <w:p>para3</w:p>
    </w:body>
</w:document>

帕拉1
表数据1
表数据2
帕拉2
表数据3
表数据4
表数据5
表数据6
帕拉3
…产生

<root>
   <p>para1<table>table data 1</table>
      <table>table data 2</table>
   </p>
   <p>para2<table>table data 3</table>
      <table>table data 4</table>
      <table>table data 5</table>
      <table>table data 6</table>
   </p>
   <p>para3</p>
</root>

平行表数据1
表数据2

准表数据3 表数据4 表数据5 表数据6

帕拉3


谢谢你,蒂姆。请告诉我,如果我的当前上下文节点是table data 1,那么它是否适用于这种情况?否,只有当您的当前上下文是w:p元素时,此解决方案才有效。谢谢Tim。请告诉我,如果我当前的上下文节点是table data 1,那么它是否适用于这种情况?否,只有当您当前的上下文是w:p元素时,此解决方案才有效。