我有一个XML文档,我使用XSLT 1.0进行转换:
<?xml version="1.0" encoding="UTF-8"?>
<element tag="container">
<data handle="$1">
...
</data>
<assignments/>
<expression context="$1">
Object_Text
</expression>
<expression context="$1">
Object_Text
</expression>
<expression context="$1">
Object_Heading
</expression>
<element tag="container">
<data handle="$2">
...
</data>
<assignments/>
<element tag="container">
<data handle="$3">
...
</data>
<assignments/>
<expression context="$3">
Object_Text
</expression>
</element>
<element tag="container">
...
</element>
</element>
<element tag="container">
<element tag="container">
<element tag="container">
<expression context="$1">
Object_Text
</expression>
</element>
</element>
</element>
<element tag="container">
<expression context="$1">
Object_Identifier
</expression>
</element>
</element>
我必须为每个表达式类型(Object_Text,Object_Heading,...)添加分配到包含标记的下一个父容器节点的标记(并非所有容器都有该标记,那些应该被忽略)并且表达式的上下文值必须符合容器的句柄值。由于我需要为每种表达式类型分配一个事实,因此无论它出现多少,我都应该在其上下文中为每种类型分配一个赋值。所以期望的输出是:
<?xml version="1.0" encoding="UTF-8"?>
<element tag="container">
<data handle="$1">
...
</data>
<assignments> <!--Added assignments here (one for each type with @context='$1')-->
<assignment name="Object_Text">
</assignment>
<assignment name="Object_Heading">
</assignment>
<assignment name="Object_Identifier">
</assignment>
</assignments>
<expression context="$1">
Object_Text
</expression>
<expression context="$1">
Object_Text
</expression>
<expression context="$1">
Object_Heading
</expression>
<element tag="container">
<data handle="$2">
...
</data>
<assignments/>
<element tag="container">
<data handle="$3">
...
</data>
<assignments> <!--Added assignments here (one for each type with @context='$3')-->
<assignment name="Object_Text">
</assignment>
</assignments>
<expression context="$3">
Object_Text
</expression>
</element>
<element tag="container">
...
</element>
</element>
<element tag="container">
<expression context="$1">
Object_Identifier
</expression>
</element>
</element>
目前,我可以使用Muenchian分组方法获得一组表达式类型(Object_Text等)。但我的问题是,我无法通过它们的属性@context区分这些表达式类型,因此容器只包含正确表达式的赋值,它实际上包含相同的@context。
我很感激任何帮助。有人知道实现所需输出的方法吗?我尝试了很多东西,但目前缺乏这方面的经验/知识。
编辑:应该补充一点,这是xml文档的示例结构。所以xslt函数应该在任意嵌套,包装结构中以及任意次数识别表达式。
答案 0 :(得分:0)
这会让你前进。你有一些抑制,这段代码没有考虑到。
<!-- Handle each container that has an assignments node. -->
<xsl:template match="element[@tag='container' and .//assignments]">
<!-- Bind to the expressions for this container. -->
<xsl:variable name="expressions" select="expression"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="expressions" select="$expressions"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<!-- Create the assignments for each container. -->
<xsl:template match="assignments">
<xsl:param name="expressions"/>
<xsl:copy>
<xsl:for-each select="$expressions">
<xsl:element name="assignment">
<xsl:attribute name="name">
<xsl:value-of select="normalize-space(.)"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<!-- Identity template. -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
答案 1 :(得分:0)
让我们首先声明表达式的键
<xsl:key name="kExp" match="expression" use="concat(@context, '|', normalize-space(.))"/>
在assignments
节点下,我们将放置第一个前兄弟节点@handle
的{{1}}属性
data
在<xsl:variable name="dataHandle" select="preceding-sibling::data/@handle"/>
节点中使用此变量并使用Muenchian方法(我假设表达式是assignments
node 的兄弟节点的兄弟或后代)时:
assignments
整个样式表如下:
<xsl:template match="assignments">
<xsl:variable name="dataHandle" select="preceding-sibling::data/@handle"/>
<xsl:copy>
<xsl:for-each select="../descendant::expression[@context=$dataHandle
and generate-id()=generate-id(key('kExp', concat(@context, '|', normalize-space(.)))[1])]">
<assignment name="{normalize-space(.)}"></assignment>
</xsl:for-each>
</xsl:copy>
</xsl:template>