я использую <xsl:template match="m:*/text()">
чтобы сопоставить текст в моем XML-документе, который отлично работает для простого текста и известных объектов, то есть он отлично работает для таких объектов, как &
или Unicode объекты, такие как π
,
Однако то, что не работает, это сопоставление пользовательских имен объектов. Например, у меня есть сущность π
в моем XML-документе это должно соответствовать text()
, По какой-то причине он не рассматривает эту сущность как текст, что означает, что ничто не сопоставляется.
Обратите внимание, что я объявил имя сущности в объявлении Doctype XML-документа, а также XSLT-документа:
<!DOCTYPE xsl:stylesheet [<!ENTITY pi "π">]>
Является text()
правильный подход к сопоставлению пользовательских имен объектов, или мне нужно использовать другую функцию? (Может быть, я тоже сделал что-то не так, объявив имя сущности?)
Спасибо
редактировать
XML
<!DOCTYPE mathml [<!ENTITY pi "π">]>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline">
<mi>π</mi>
<mi>test</mi>
<mi>π</mi>
</math>
XSLT
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [<!ENTITY pi "π">]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:m="http://www.w3.org/1998/Math/MathML"version='1.0'>
<xsl:template match="m:*/text()">
<xsl:call-template name="replaceEntities">
<xsl:with-param name="content" select="normalize-space()"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="replaceEntities">
<xsl:param name="content"/>
<xsl:value-of select="$content"/>
</xsl:template>
</xsl:stylesheet>
Переменная $content
должен быть напечатан три раза, однако только test
а также π
печатается.
Обработка с использованием PHP
$xslDoc = new DOMDocument();
$xslDoc->load("doc.xsl");
$xslProcessor = new \XSLTProcessor();
$xslProcessor->importStylesheet($xslDoc);
$mathMLDoc = new DOMDocument();
$mathMLDoc->loadXML('<!DOCTYPE mathml [<!ENTITY pi "π">]><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mi>π</mi><mi>test</mi><mi>π</mi></math>');
echo $xslProcessor->transformToXML($mathMLDoc);
Насколько я вижу, проблема в том, что DTD не виден в таблице стилей XSLT. Используйте следующие для замены сущностей с их текстовым значением перед преобразованием документа:
$mathMLDoc->substituteEntities = true;
как в
$xslDoc = new DOMDocument();
$xslDoc->load("tree.xsl");
$xslProcessor = new \XSLTProcessor();
$xslProcessor->importStylesheet($xslDoc);
$mathMLDoc = new DOMDocument();
$mathMLDoc->substituteEntities = true;
$mathMLDoc->loadXML('<!DOCTYPE math [<!ENTITY pi "π">]><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mi>π</mi><mi>test</mi><mi>π</mi></math>');
echo $xslProcessor->transformToXML($mathMLDoc);
который будет производить
<?xml version="1.0"?>
πtestπ
Немного предыстории: http://php.net/manual/en/xsltprocessor.transformtoxml.php#99932 а также http://hublog.hubmed.org/archives/001854.html.
Других решений пока нет …