Xml 如何获取下面的下一个直接值::node()<;w:tbl>;使用xslt2.0的上下文节点的元素?
我想通过使用xslt 2.0将一种xml格式转换为另一种xml格式。现在,我想获取上下文节点的下一个紧挨着的::node()元素 这是我的xml文档: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"
<?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元素时,此解决方案才有效。