什么是更好的XSL样式方法来创建HTML标记?

时间:2013-01-04 22:24:22

标签: html xslt xslt-1.0

我有一个相当简单的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>

建议?

2 个答案:

答案 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属性中使用谓词过滤器, HtmlElementxsl: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>