我对xslt很新,正在进行第一次转换。
以下是我的XML文件的一部分示例:
<inline-formula id="if1">
<f>
<b>AB
<mit>CD</mit>
EF</b>=
<g>d</g>
<sup>2</sup>
<inf>1</inf>
</f>
</inline-formula>
使用xslt 2.0,我想取消<mit>
元素中的<b>
元素:
<inline-formula id="if1">
<f>
<b>AB</b>
<mit>CD</mit>
<b>EF</b>=
<g>d</g>
<sup>2</sup>
<inf>1</inf>
</f>
</inline-formula>
在任何嵌套组合中都有15个这样的元素,所以理想情况下代码可以让我不用任何可能的组合。
我已经查看了很多关于XML文件扁平化的问题,但到目前为止我没有尝试过任何问题。任何帮助或提示将不胜感激。
答案 0 :(得分:1)
我想取消
中的<mit>
元素<b>
元素
这不完全是你的例子所显示的。为了获得预期的结果,您必须(a)删除现有的b
包装器,并(b)为b
的每个文本节点子项创建一个新的b
元素:
XSLT 1.0 / 2.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="b">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="b/text()">
<b>
<xsl:value-of select="normalize-space(.)"/>
</b>
</xsl:template>
</xsl:stylesheet>
任何嵌套都可能出现15个这样的元素 组合,所以理想情况下代码会允许我不再使用任何组合 可能的组合。
不确定这意味着什么。
答案 1 :(得分:0)
这会为你做诀窍......?
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="inline-formula/*/*[* and text()]">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="inline-formula/*/*[*]/text()">
<xsl:element name="{local-name(parent::*)}">
<xsl:value-of select="normalize-space()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这看起来是inline-formula
元素的“孙子”,它恰好混合了文本和元素子元素,对于文本元素,它将它们包装在父标记的副本中。
答案 2 :(得分:0)
下面的转换使用了复制转换,并匹配f
或f1
中还具有嵌套元素的元素。
对于匹配的项目,它以递归方式展平元素。
这比Tim C的答案更复杂。但是,这可以用于更多级别的嵌套。
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[self::f | self::f1]/*[*]">
<xsl:call-template name="flattenElement">
<xsl:with-param name="pElement" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="flattenElement">
<xsl:param name="pElement" as="element()" />
<xsl:for-each select="$pElement/node()">
<xsl:choose>
<xsl:when test="self::*">
<xsl:call-template name="flattenElement">
<xsl:with-param name="pElement" select="."/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{local-name($pElement)}">
<xsl:sequence select="normalize-space()"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>