我想转换属性长度为
的xml空元素标签<tag length=”3”/>xxxxxxx
进入开始标记和结束标记
<tag>xxx</tag>xxxx
使用C#或XSLT
你有个主意吗?
来自:
<comment>
<opinion id="tag_1" length="93"/>
Un bon traiteur Findi Traiteur propose un choix de
<topicInstance id="tag_2" length="13"/>
pâtes cuites à la minute et d'
<topicInstance id="tag_3" length="9"/>
antipasti.
</comment>
致:
<comment>
<opinion id="tag_1">
Un bon traiteur Findi Traiteur propose un choix de
<topicInstance id="tag_2">
pâtes cuites</topicInstance> à la minute et d'
<topicInstance id="tag_3">
antipasti</topicInstance>.
</opinion>
</comment>
答案 0 :(得分:1)
以下是实现所需处理的完整而简单的转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@length]">
<xsl:variable name="vFollowingText" select=
"normalize-space(following-sibling::text()[1])"/>
<xsl:copy>
<xsl:apply-templates select="@*[not(name()='length')]"/>
<xsl:value-of select="substring($vFollowingText, 1, @length)"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:value-of select="substring($vFollowingText, @length+1)"/>
</xsl:template>
<xsl:template match="text()[preceding-sibling::*[1][@length]]"/>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<comment>
<opinion id="tag_1" length="93"/>
Un bon traiteur Findi Traiteur propose un choix de
<topicInstance id="tag_2" length="13"/>
pâtes cuites à la minute et d'
<topicInstance id="tag_3" length="9"/>
antipasti.
</comment>
产生了想要的正确结果:
<comment>
<opinion id="tag_1">Un bon traiteur Findi Traiteur propose un choix de</opinion><topicInstance id="tag_2">pâtes cuites </topicInstance>à la minute et d'<topicInstance id="tag_3">antipasti</topicInstance>.</comment>
<强>更新强>:
根据@enguerran的评论,<opinion>
应该包含其余的内容,这里有一个转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@length]" mode="following">
<xsl:variable name="vFollowingText" select=
"normalize-space(following-sibling::text()[1])"/>
<xsl:copy>
<xsl:apply-templates select="@*[not(name()='length')]"/>
<xsl:value-of select="substring($vFollowingText, 1, @length)"/>
<xsl:apply-templates/>
</xsl:copy>
<xsl:value-of select="substring($vFollowingText, @length+1)"/>
</xsl:template>
<xsl:template match="*[@length and not(preceding-sibling::*/@length)]">
<xsl:copy>
<xsl:apply-templates select="@*[not(name()='length')]"/>
<xsl:apply-templates select="node()"/>
<xsl:apply-templates mode="following" select=
"following-sibling::text()[1] |following-sibling::*" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[preceding-sibling::*[1][@length]] | text()"/>
</xsl:stylesheet>
在提供的XML文档(上面)上应用此转换时,会生成所需的正确结果:
<comment>
<opinion id="tag_1">
Un bon traiteur Findi Traiteur propose un choix de
<topicInstance id="tag_2">pâtes cuites </topicInstance>à la minute et d'<topicInstance id="tag_3">antipasti</topicInstance>.</opinion>
</comment>
答案 1 :(得分:0)
这可能在某种程度上满足您的要求:
<xsl:template match="comment/opinion|comment/topicInstance">
<xsl:copy>
<!-- copy attributes except for "length" -->
<xsl:for-each select="@*[local-name() != 'length']">
<xsl:copy/>
</xsl:for-each>
<!-- include characters from the following text node -->
<xsl:value-of select="substring(following-sibling::text()[1], 1, @length)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="comment/text()">
<xsl:variable name="previous" select="preceding-sibling::node()[1]"/>
<!-- strip characters that have been inserted in the previous node -->
<xsl:value-of select="substring(*, $previous/@length + 1)"/>
</xsl:template>
它不会涵盖所有情况,您需要添加一些检查(例如检查前一个节点是否存在等)。