Как уже указывалось, ваш входной образец не является правильно сформированным XML, поэтому стандартная цепочка обработки XPath или XSLT, где используется синтаксический анализатор XML для анализа входных данных XML, работать не будет.
Однако некоторые процессоры XSLT или XPath позволяют подключать анализатор HTML вместо анализатора XML к цепочке обработки, и таким образом вы также можете анализировать исходный ввод и значение атрибута для использования XPath.
Кроме того, с XSLT 2 и 3 вы можете использовать реализацию синтаксического анализатора HTML Дэвида Карлайла, выполненную в чистом XSLT 2 https://github.com/davidcarlisle/web-xslt/blob/master/htmlparse/htmlparse.xsl из любой таблицы стилей XSLT 2 или более поздней, для анализа HTML, который у вас есть как строка, поэтому либо передается как строковый параметр или экранирование в разделе CDATA во вводе XML или чтение с использованием unparsed-text
.
Использование функций этого синтаксического анализатора HTML позволяет затем дважды вызвать его функцию htmlparse
и выбрать элемент b
, например, с помощью. dpc:htmlparse($html-input, '', true())/div[@data-content]/dpc:htmlparse(@data-content, '', true())/b
или его содержание, например, dpc:htmlparse($html-input, '', true())/div[@data-content]/dpc:htmlparse(@data-content, '', true())/b/string()
.
Полная таблица стилей XSLT будет
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:dpc="data:,dpc"
exclude-result-prefixes="#all"
version="3.0">
<xsl:import href="https://github.com/davidcarlisle/web-xslt/raw/master/htmlparse/htmlparse.xsl"/>
<xsl:param name="html-input" as="xs:string"><![CDATA[<div data-content="<i>10%</i><b>C</b>"></div>]]></xsl:param>
<xsl:template name="xsl:initial-template" match="/">
<xsl:copy-of select="dpc:htmlparse($html-input, '', true())/div[@data-content]/dpc:htmlparse(@data-content, '', true())/b/string()"/>
</xsl:template>
</xsl:stylesheet>
Онлайн-демонстрации на
Если вы привязаны к PHP и его поддержке XPath 1.0, то у вас есть возможность запустить XPath 1.0, расширенный функциями PHP, против DOMDocument, созданного с помощью loadHTML
из строки HTML:
$html = <<<EOT
<div data-content="<i>10%</i><b>C</b>"></div>
EOT;
$domDoc = new DOMDocument();
$domDoc->loadHTML($html);
function parseXmlFragment($fragment) {
$docFrag = $fragment[0]->ownerDocument->createDocumentFragment();
$docFrag->appendXML($fragment[0]->textContent);
return $docFrag;
}
$xpath = new DOMXPath($domDoc);
$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPHPFunctions("parseXmlFragment");
echo $xpath->evaluate("string(php:function('parseXmlFragment', //div[@data-content]/@data-content)/b)", $domDoc);
См. https://www.php.net/manual/en/domdocument.loadhtml.php, https://www.php.net/manual/en/domdocumentfragment.appendxml.php и https://www.php.net/manual/en/domxpath.registerphpfunctions.php.