【问题标题】:Apply transforms to XML attribute containing escaped HTML将转换应用于包含转义 HTML 的 XML 属性
【发布时间】:2014-11-19 13:37:04
【问题描述】:

我有一些看起来像这样的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <issue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <comment text="&lt;div class=&quot;wiki text&quot;&gt;&lt;h4&gt;Tom Fenech&lt;/h4&gt;Here is a comment&lt;/div&gt;&#10;"/>
    </issue>
</root>

如您所见,comment 节点中的text 属性包含转义的 HTML。我想将属性的内容作为 XHTML 获取,我目前在模板中使用:

<xsl:value-of select="@text" disable-output-escaping="yes" />

这让我得到了最终输出中的 HTML:

<div class="wiki text"><h4>Tom Fenech</h4>Here is a comment</div>

但我希望能够提取&lt;h4&gt; 标记的内容以在其他地方使用。一般来说,一旦它被转义,能够操纵它的内容会很好。

如何将更多模板应用于&lt;xsl:value-of /&gt; 的输出?

我目前正在使用PHP built-in XSLT processor,它支持 XSLT 1.0 版,但如果新版本的功能使这成为可能,我愿意考虑使用替代处理器。

【问题讨论】:

  • 您使用或可以使用哪种 XSLT 处理器? Saxon 9.6 HE 版本是一个 XSLT 3.0 处理器,它允许您使用 &lt;xsl:apply-templates select="parse-xml(@text)/node()"/&gt; 或者更好的 &lt;xsl:apply-templates select="parse-xml-fragment(@text)/node()"/&gt;。见w3.org/TR/xpath-functions-30/#func-parse-xml。如果你想使用value-ofdisable-output-escaping,那么你总是需要两个样式表,第一个使用disable-output-escaping 输出属性值,第二个使用第一个的结果。
  • @Martin 我正在使用 PHP 附带的 XSLT 处理器(仅支持 1.0 版)。我已经更新了这个问题。我知道可以在 PHP 中使用其他 XSLT 处理器(例如 Saxon),所以我仍然会对使用更现代版本的功能的解决方案感兴趣。

标签: xml xslt


【解决方案1】:

这是您可以做到的一种方法,通过从 XSLT 调用 PHP 函数:

function parseHTMLString($html)
{
    $doc = new DOMDocument();
    $doc->loadHTML($html);
    return $doc;
}

$xml = <<<EOB
<root>
    <issue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <comment text="&lt;div class=&quot;wiki text&quot;&gt;&lt;h4&gt;Tom Fenech&lt;/h4&gt;Here is a comment&lt;/div&gt;&#10;"/>
    </issue>
</root>
EOB;

$xsl = <<<EOB
<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:php="http://php.net/xsl"
     xsl:extension-element-prefixes="php">
<xsl:output method="html" encoding="utf-8" indent="yes"/>
 <xsl:template match="comment">
   <xsl:apply-templates select="php:functionString('parseHTMLString', @text)//div/h4"/>
 </xsl:template>

 <xsl:template match="div/h4">
   <h2><xsl:apply-templates/></h2>
 </xsl:template>
</xsl:stylesheet>
EOB;

$xmldoc = new DOMDocument();
$xmldoc->loadXML($xml);

$xsldoc = new DOMDocument();
$xsldoc->loadXML($xsl);

$proc = new XSLTProcessor();
$proc->registerPHPFunctions('parseHTMLString');
$proc->importStyleSheet($xsldoc);
echo $proc->transformToXML($xmldoc);

【讨论】:

  • 令人印象深刻,谢谢!进行了一些更改以使其正常工作 - 我必须将 xsl:extension-element-prefixes="php" 添加到开始标记并更改函数调用的语法。
【解决方案2】:

您不能将模板应用于未解析(转义或 CDATA)的文本。查看一些可能与您相关的先前答案:

Parsing html with xslt

XSLT: Reading a param that's an xml document passed as a string

how to parse the xml inside CDATA of another xml using xslt?

【讨论】:

  • 感谢您的链接 - 我怀疑这在 XSLT 中可能无法实现,但希望有办法解决它。
猜你喜欢
  • 2018-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 2015-10-10
相关资源
最近更新 更多