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



我有一个相当简单的xsl样式表,用于将定义html的xml文档转换为html格式(请不要问为什么,这只是我们必须这样做的方式…)

<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>

建议吗?

你可以简单地为Text元素添加一个新规则,然后匹配HTMLElements和Text:

<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>

您可以使样式表更通用一点,以便通过调整HtmlElement的模板来处理额外的元素,以确保它首先将模板应用于Attributes元素,然后通过在xsl:apply-templates的select属性中使用谓词过滤器将模板应用于除 AttributesHtmlElement元素之外的所有元素

内置模板将匹配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>

相关内容

  • 没有找到相关文章

最新更新