1

我在尝试使用 XSLT 处理一大块 HTML 时遇到了一些奇怪的行为。我正在尝试用图形元素替换 img 元素。该元素被替换,但周围的包装元素随后出现两次,一次在图形元素之前,一次在之后。下面的例子说明了这个问题。Saxon 9.0.0.8 和 9.1.0.8(我们的 CMS 的两个不同版本)中都存在问题

我正在处理的 HTML 如下:

    <p class="editor-p-block">
      <img alt="Untitled-2" src="image://11?_size=full" title="Untitled-2" />
    </p>

模板如下:

<xsl:template name="stk:html.process">
    <xsl:param name="document" as="element()"/>
    <xsl:apply-templates select="$document/*|$document/text()" mode="html.process"/>   
</xsl:template>

<xsl:template match="element()" mode="html.process">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="*|text()|@*" mode="html.process"/>
  </xsl:element>
</xsl:template>

<xsl:template match="img" mode="html.process">
   <xsl:element name="figure"/>
</xsl:template>

<xsl:template match="text()|@*" mode="html.process">
   <xsl:copy/>
</xsl:template>

这会产生以下 HTML:

    <p class="editor-p-block">         
    </p>
    <figure></figure>
    <p></p>  

我在这里做错了什么?

编辑:完全可重现的例子:

<xsl:output method="xhtml"/>

<xsl:template match="/">

    <xsl:variable name="document" as="element()">
        <content xmlns="">
            <p class="editor-p-block">
                <img alt="Untitled-2" src="image://11?_size=full" title="Untitled-2"/>
            </p>
        </content>
    </xsl:variable>

    <xsl:call-template name="stk:html.process">
        <xsl:with-param name="document" select="$document"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="stk:html.process">
    <xsl:param name="document" as="element()"/>
    <div class="editor">
        <xsl:apply-templates select="$document/*|$document/text()" mode="html.process"/>
    </div>
</xsl:template>

<xsl:template match="element()" mode="html.process">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="*|text()|@*" mode="html.process"/>
    </xsl:element>
</xsl:template>

<xsl:template match="img" mode="html.process">
    <xsl:element name="figure"/>
</xsl:template>

<xsl:template match="text()|@*" mode="html.process">
    <xsl:copy/>
</xsl:template>

4

3 回答 3

0

我无法重现该问题,使用 Saxon 9.5 HE Java 和以下示例:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:stk="http://example.com/so">

<xsl:output method="xhtml"/>

<xsl:template match="/">

    <xsl:variable name="document" as="element()">
        <content xmlns="">
            <p class="editor-p-block">
                <img alt="Untitled-2" src="image://11?_size=full" title="Untitled-2"/>
            </p>
        </content>
    </xsl:variable>

    <xsl:call-template name="stk:html.process">
        <xsl:with-param name="document" select="$document"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="stk:html.process">
    <xsl:param name="document" as="element()"/>
    <div class="editor">
        <xsl:apply-templates select="$document/*|$document/text()" mode="html.process"/>
    </div>
</xsl:template>

<xsl:template match="element()" mode="html.process">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="*|text()|@*" mode="html.process"/>
    </xsl:element>
</xsl:template>

<xsl:template match="img" mode="html.process">
    <xsl:element name="figure"/>
</xsl:template>

<xsl:template match="text()|@*" mode="html.process">
    <xsl:copy/>
</xsl:template>

</xsl:stylesheet>

针对任何输入 XML 运行我得到输出

<?xml version="1.0" encoding="UTF-8"?><div xmlns:stk="http://example.com/so" class="editor">
   <p class="editor-p-block">
      <figure></figure>
   </p>
</div>
于 2013-05-30T11:57:10.163 回答
0

您可以在 CMS 之外使用 Saxon 重现该问题吗?如果没有,手指指向您的 CMS...

于 2013-05-31T08:05:15.700 回答
0

经过更多调查,我找到了这个问题的解释。它根本与 XSLT 处理无关。

事实证明,HTML 标准不允许您将图形元素放在 ap 元素中。一个 p 元素只能包含所谓的“短语内容”,其中包括以下元素:

<abbr>, <audio>, <b>, <bdo>, <br>, <button>, <canvas>, <cite>, <code>, <command>, <datalist>, <dfn>, <em>, <embed>, <i>, <iframe>, <img>, <input>, <kbd>, <keygen>, <label>, <mark>, <math>, <meter>, <noscript>, <object>, <output>, <progress>, <q>, <ruby>, <samp>, <script>, <select>, <small>, <span>, <strong>, <sub>, <sup>, <svg>, <textarea>, <time>, <var>, <video>, <wbr> and plain text (not only consisting of white spaces characters).

因此,在我的测试中使用的浏览器开发工具只是将元素移到了外部,并且由于某种原因还创建了一个重复的包装器元素。如果我用 ie img 或 strong 替换 figure ,问题就消失了。

于 2013-05-31T08:18:40.303 回答