我有一个相当简单的xsl样式表,用于转换将我们的html定义为html格式的xml文档(请不要问为什么,这只是我们必须这样做的方式......)
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="HtmlElement">
<xsl:element name="{ElementType}">
<xsl:apply-templates select="Attributes"/>
<xsl:value-of select="Text"/>
<xsl:apply-templates select="HtmlElement"/>
</xsl:element>
</xsl:template>
<xsl:template match="Attributes">
<xsl:apply-templates select="Attribute"/>
</xsl:template>
<xsl:template match="Attribute">
<xsl:attribute name="{Name}">
<xsl:value-of select="Value"/>
</xsl:attribute>
</xsl:template>
当我遇到需要转换的这一点HTML时出现了这个问题:
<p>
Send instant ecards this season <br/> and all year with our ecards!
</p>
中间的<br/>
打破了转换的逻辑,只给出了段落块的前半部分:Send instant ecards this season <br></br>
。尝试转换的XML看起来像:
<HtmlElement>
<ElementType>p</ElementType>
<Text>Send instant ecards this season </Text>
<HtmlElement>
<ElementType>br</ElementType>
</HtmlElement>
<Text> and all year with our ecards!</Text>
</HtmlElement>
建议?
答案 0 :(得分:1)
您只需为Text元素添加新规则,然后匹配HTMLElements和文本:
<xsl:template match="HtmlElement">
<xsl:element name="{ElementName}">
<xsl:apply-templates select="Attributes"/>
<xsl:apply-templates select="HtmlElement|Text"/>
</xsl:element>
</xsl:template>
<xsl:template match="Text">
<xsl:value-of select="." />
</xsl:template>
答案 1 :(得分:0)
您可以通过调整HtmlElement
的模板来使样式表更加通用,以确保它首先将模板应用于Attributes
元素,然后应用于所有元素<通过在Attributes
的select属性中使用谓词过滤器, 除 HtmlElement
和xsl:apply-templates
元素外。
内置模板将与Text
元素匹配,并将text()
复制到输出。
此外,您可以删除当前声明的根节点的模板(即match="/"
)。它只是重新定义内置模板规则已经处理的内容,并且不会做任何改变行为的事情,只会使样式表变得混乱。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<!-- <xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>-->
<xsl:template match="HtmlElement">
<xsl:element name="{ElementType}">
<xsl:apply-templates select="Attributes"/>
<!--apply templates to all elements except for ElementType and Attributes-->
<xsl:apply-templates select="*[not(self::Attributes|self::ElementType)]"/>
</xsl:element>
</xsl:template>
<xsl:template match="Attributes">
<xsl:apply-templates select="Attribute"/>
</xsl:template>
<xsl:template match="Attribute">
<xsl:attribute name="{Name}">
<xsl:value-of select="Value"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>