Html 替换XSLT中的元素会导致包装器元素出现两次(Saxon)
我在尝试用XSLT处理一大块HTML时遇到了一些奇怪的行为。我试图用一个figure元素替换img元素。元素被替换,但是周围的包装器元素会出现两次,一次在figure元素之前,一次在figure元素之后。下面的例子说明了这个问题。这个问题存在于Saxon 9.0.0.8和9.1.0.8(我们CMS的两个不同版本)中 我正在处理的HTML如下所示:Html 替换XSLT中的元素会导致包装器元素出现两次(Saxon),html,xslt,saxon,Html,Xslt,Saxon,我在尝试用XSLT处理一大块HTML时遇到了一些奇怪的行为。我试图用一个figure元素替换img元素。元素被替换,但是周围的包装器元素会出现两次,一次在figure元素之前,一次在figure元素之后。下面的例子说明了这个问题。这个问题存在于Saxon 9.0.0.8和9.1.0.8(我们CMS的两个不同版本)中 我正在处理的HTML如下所示: <p class="editor-p-block"> <img alt="Untitled-2" src="im
<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>
模板如下:
<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>
我做错了什么
编辑:完整的可复制示例:
使用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>
您能在CMS之外使用Saxon重现问题吗?如果没有,手指指向您的CMS…经过进一步调查,我找到了这个问题的解释。它与XSLT处理毫无关系
事实证明,HTML标准不允许将figure元素放入p元素中。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).
,
,,,,,,,,,,,,,,,,,,,,,,,,和纯文本(不仅仅由空格字符组成)。
因此,在我的测试中使用的浏览器开发工具只是将元素移到了外部,并且出于某种原因还创建了一个重复的包装器元素。
如果我用img或strong替换数字,问题就会消失。考虑发布小而完整的样本,以便我们重现问题。如果有,您在哪里调用stk:html.process
?哪个是上下文节点,您在哪里设置参数?好的,这是一个完全可复制的示例:我使用的CMS使用的是Saxon 9.0.0.8,在使用9.1.0.8的较新版本中也存在此问题。我刚刚用Saxon 9.1.0.8 B尝试了上面的示例,输出是
。