考虑我有这个XML文件:
<p>my name is :
<bold>reza</bold>
<bold>saket</bold>
<bold>ali</bold>
<bold>abadi</bold>
</p>
<p>my name is :
<bold>
<italic>mehran</italic>
</bold>
<bold>
<italic>bazargan</italic>
</bold>
<bold>
<italic>dashtestani</italic>
</bold>
</p>
现在我希望输出结果为:
<p> my name is :
<bold>reza saket ali abadi</bold>
</p>
<p>
<bold>
<italic>mehran bazargan dashtestani</italic>
</bold>
</p>
答案 0 :(得分:0)
我会编写一个身份转换,然后通过添加这样的模板(未测试)来修改它。首先,对粗体和斜体元素进行特殊处理:
<xsl:template match='bold | italic'>
<xsl:variable name="name" select="name()"/>
<xsl:choose>
<!--* if our preceding sibling has the same element
* type, then we have already been processed;
* do nothing. *-->
<xsl:when test="preceding-sibling::*[1][name() = $name]"/>
<!--* if our next following sibling has the same element
* type, then incorporate it. *-->
<xsl:when test="following-sibling::*[1][name() = $name]">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select="following-sibling::node()[1]"
mode="incorporation"/>
</xsl:copy>
</xsl:when>
<!--* otherwise, proceed normally *-->
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
然后,模板处理我们在整合模式中可能遇到的所有节点类型:
<xsl:template match='bold | italic' mode="incorporation">
<xsl:variable name="name" select="name()"/>
<xsl:apply-templates select="node()"/>
<!--* if our next following sibling has the same element
* type, then incorporate it. *-->
<xsl:if test="following-sibling::*[1][name() = $name]">
<xsl:apply-templates select="following-sibling::node()[1]"
mode="incorporation"/>
</xsl:if>
</xsl:template>
<xsl:template match='comment()'
mode='incorporation'>
<xsl:comment>
<xsl:value-of select="."/>
</xsl:comment>
<xsl:apply-templates select="following-sibling::node()[1]"
mode="incorporation"/>
</xsl:template>
<xsl:template match='processing-instruction()'
mode='incorporation'>
<xsl:variable name="pitarget" select="name()"/>
<xsl:processing-instruction name="{$pitarget}">
<xsl:value-of select="."/>
</xsl:processing-instruction>
<xsl:apply-templates select="following-sibling::node()[1]"
mode="incorporation"/>
</xsl:template>
<!--* this one accidentally omitted in first version *-->
<xsl:template match='text()' mode='incorporation'>
<xsl:value-of select="."/>
<xsl:apply-templates select="following-sibling::node()[1]"
mode="incorporation"/>
</xsl:template>
最后,模板用于抑制我们在组合模式中遇到的节点,以防止重复:
<xsl:template match='node()[not(self::*)
and preceding-sibling::*[1]
[self::bold or self::italic]]'/>
这只处理一个粗体或斜体;因为你想要嵌套它们,就像在你的第二个例子中那样,你需要运行它两次 - 或重复运行它,直到它的输出与它的输入相同,如果你可能有大于两个深的嵌套粗体和斜体元素。 / p>