我正在尝试使用XSLT处理一大块HTML时遇到一些奇怪的行为。我试图用图元素替换img元素。元素被替换,但是周围的包装元素然后出现两次,一次出现在figure元素之前,一次出现之后。下面的例子说明了这个问题。 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>
答案 0 :(得分: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>
答案 1 :(得分:0)
您可以在CMS外使用Saxon重现问题吗?如果没有,手指指向您的CMS ...
答案 2 :(得分:0)
经过更多调查,我找到了解决这个问题的方法。它根本与XSLT处理无关。
事实证明,HTML标准不允许您将图元素放在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替换数字,问题就会消失。