我输入了这样或不同的XML文档:
<X3D version="3.2">
<Scene>
<Background skyColor="1 1 1"/>
<Viewpoint position="0 0 4"/>
<Transform DEF="body_0">
<Inline url="body_0.x3d"/>
<Transform DEF="body_1" translation="0,0.2,0">
<Inline url="body_1.x3d"/>
<Transform DEF="body_2" translation="0,0,0">
<Inline url="body_2.x3d"/>
<Transform DEF="body_3" translation="0,0,0">
<Inline url="body_3.x3d"/>
<Transform DEF="body_4" translation="0.5,0,0">
<Inline url="body_4.x3d"/>
<Transform DEF="body_5" translation="0,0,0">
<Inline url="body_5.x3d"/>
</Transform>
</Transform>
</Transform>
</Transform>
<Transform DEF="body_6" translation="0,0,0">
<Inline url="body_6.x3d"/>
<Transform DEF="body_7" translation="0,0,0">
<Inline url="body_7.x3d"/>
<Transform DEF="body_8" translation="0.5,0,0">
<Inline url="body_8.x3d"/>
<Transform DEF="body_9" translation="0,0,0">
<Inline url="body_9.x3d"/>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
</Scene>
</X3D>
&#13;
我需要将具有特定属性DEF的节点包装到另一个节点。例如,属性在变量$ find中计算。所以我有xslt-stylesheet:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="find" select="concat('body_','3')"/>
<xsl:for-each-group select="//Transform"
group-adjacent="@DEF = $find">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<Transform rotation="1 0 0 1.57">
<xsl:sequence select="current-group()"/>
</Transform>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
&#13;
我希望看到下一个代码的输出文档:
<X3D version="3.2">
<Scene>
<Background skyColor="1 1 1"/>
<Viewpoint position="0 0 4"/>
<Transform DEF="body_0">
<Inline url="body_0.x3d"/>
<Transform DEF="body_1" translation="0,0.2,0">
<Inline url="body_1.x3d"/>
<Transform DEF="body_2" translation="0,0,0">
<Inline url="body_2.x3d"/>
<Transform rotation="1 0 0 1.57">
<Transform DEF="body_3" translation="0,0,0">
<Inline url="body_3.x3d"/>
<Transform DEF="body_4" translation="0.5,0,0">
<Inline url="body_4.x3d"/>
<Transform DEF="body_5" translation="0,0,0">
<Inline url="body_5.x3d"/>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
<Transform DEF="body_6" translation="0,0,0">
<Inline url="body_6.x3d"/>
<Transform DEF="body_7" translation="0,0,0">
<Inline url="body_7.x3d"/>
<Transform DEF="body_8" translation="0.5,0,0">
<Inline url="body_8.x3d"/>
<Transform DEF="body_9" translation="0,0,0">
<Inline url="body_9.x3d"/>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
</Scene>
</X3D>
&#13;
但样式表没有任何影响或节点太多。 我知道很多依赖于我在select属性中指定的参数,但我仍然无法找到解决方案 我怎么能丰富它?
接下来我试着给出一个使用它的例子。 在下面的代码中,我使用了一个在tamplate&#34; getlistOfBodies&#34;
中形成的字符串列表。
<xsl:variable name="listOfBodies">
<xsl:call-template name="getlistOfBodies">
</xsl:call-template>
</xsl:variable>
<xsl:template match="*[Transform]">
<xsl:call-template name="wrap">
<xsl:with-param name="search" select="$listOfBodies" />
<!-- examples of $listOfBodies: "'body_2', 'body_5','body_6'" -->
</xsl:call-template>
</xsl:template>
<xsl:template name="wrap" >
<xsl:param name="search" select="0"/>
<xsl:copy>
<xsl:for-each-group select="* | @*" group-adjacent="@DEF = $search">
<!-- ... ->
&#13;
所以我希望看到下一个输出取决于$ search: (让$ search =&#34;&#39; body_2&#39;,&#39; body_6&#39;&#34;)
<?xml version="1.0" encoding="UTF-8"?>
<X3D version="3.2">
<Scene>
<Background skyColor="1 1 1"/>
<Viewpoint position="0 0 4"/>
<Transform DEF="body_0">
<Inline url="body_0.x3d"/>
<Transform DEF="body_1" translation="0,0.2,0">
<Inline url="body_1.x3d"/>
<Transform rotation="1 0 0 1.57">
<Transform DEF="body_2" translation="0,0,0">
<Inline url="body_2.x3d"/>
<Transform DEF="body_3" translation="0,0,0">
<Inline url="body_3.x3d"/>
<Transform DEF="body_4" translation="0.5,0,0">
<Inline url="body_4.x3d"/>
<Transform DEF="body_5" translation="0,0,0">
<Inline url="body_5.x3d"/>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
<Transform rotation="1 0 0 1.57">
<Transform DEF="body_6" translation="0,0,0">
<Inline url="body_6.x3d"/>
<Transform DEF="body_7" translation="0,0,0">
<Inline url="body_7.x3d"/>
<Transform DEF="body_8" translation="0.5,0,0">
<Inline url="body_8.x3d"/>
<Transform DEF="body_9" translation="0,0,0">
<Inline url="body_9.x3d"/>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
</Transform>
</Scene>
</X3D>
&#13;
如果$ search =&#34;&#39; body_2&#39;,&#39; body_3&#39;&#34;然后应该用两个不同的翻译包裹两个节点(DEF =&#39; body_2&#39;,DEF =&#39; body_3&#39;)。如果变量中的字符串数为6,那么六个节点应该包含六个变换。 它是这样的......
答案 0 :(得分:1)
如果你使用正确级别的分组并通过身份转换处理其余的分组(例如在带有xsl:mode on-no-match="shallow-copy"
的XSLT 3中),那么你得到
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:param name="search" as="xs:string">body_3</xsl:param>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*[Transform/@DEF = $search]">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="@DEF = $search">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<Transform rotation="1 0 0 1.57">
<xsl:apply-templates select="current-group()"/>
</Transform>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
根据您的评论和编辑,听起来好像您根本不想包装相邻元素,只是想将某些元素包装到新的Transform
中,如下面的代码所示:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:param name="def-list" as="xs:string*" select="'body_2','body_3'"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Transform[@DEF = $def-list]">
<Transform rotation="1 0 0 1.57">
<xsl:next-match/>
</Transform>
</xsl:template>
</xsl:stylesheet>
因此参数现在是一个字符串序列(xs:string*
),任何Transform
元素的DEF
元素等于序列中的一个值被包装成一个新的{ {1}}元素。