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

3

我有一个非常简单的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/>打破了转化逻辑,使我只得到段落块的前半部分:发送即时电子贺卡本季<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个回答

1

您可以为文本元素添加新规则,然后匹配HTMLElements和Texts:

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

现在这会影响到一个 <i>...</i> 标签吗?我不确定我理解你的回答的方向。 - CallMeTroggy
@CallMeTroggy 首先,这个XSL会根据你在问题中指定的XML输入生成所需的HTML输出。这应该是个好消息 ;) 只要遵循你在问题中提出的XML结构,它也可以完美地处理任何嵌套的HTML元素 - 试试看吧! - phihag
啊哈!是的,这正是我所需要的。我对XSL还比较新,以前没有真正看到/理解过管道的作用(现在还有点不确定,但更好地掌握了)。谢谢@phihag! - CallMeTroggy

0

为了处理额外的元素,可以使样式表更加通用,通过调整HtmlElement模板确保首先将模板应用于Attributes元素,然后再通过在xsl:apply-templates的选择属性中使用谓词过滤器将模板应用于除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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接