使用 PHP 和 XPATH 渲染嵌入在 XML 节点中的 XML 节点
Using PHP and XPATH to render XML nodes embedded within an XML node
我正在尝试解析带有 PHP 命名空间的 XML 文档以输出 HTML,并保留其原始结构。
我在下面的代码中使用了 XPATH 和 foreach 循环来呈现标题、段落和列表,但这不符合文档的原始结构。我也不清楚如何渲染嵌入在内容中的 URL 之类的内容,这些内容也包含在 XML 标签中。
XML 示例:
<a:section>
<c:ref value="1">1</c:ref>
<c:title>Title of content</c:title>
<f:subsection>
<c:ref value="1.1">1.1</c:ref>
<c:title>Subsection title</c:title>
<b:content>Make sure you check out this link: <c:url address="www.google.com" type="https">google.com</c:url> and then review the list below:</b:content>
<c:list type="bullet">
<c:listitem>
<b:content>bullet item 1</b:content>
</c:listitem>
<c:listitem>
<b:content>bullet item 2</b:content>
</c:listitem>
<c:listitem>
<b:content>bullet item 3</b:content>
</c:listitem>
</c:list>
<b:content>More content here in text form</b:content>
</f:subsection>
</a:section>
PHP 示例:
$xml = file_get_contents('content.xml');
$sxml = new SimpleXmlElement($xml);
$section = $sxml->xpath('//a:section');
foreach ($section as $s) {
$sectionnumber = $s->xpath('c:ref');
$title = $s->xpath('c:title');
foreach ($title as $t) {
echo '<h2>'.$sectionnumber[0].' '.$t.'</h2>';
}
}
$subsection = $s->xpath('f:subsection');
foreach ($subsection as $ss) {
$subheadingnumber = $ss->xpath('c:ref');
$subheading = $ss->xpath('c:title');
foreach ($subheading as $sh) {
echo '<h3>'.$subheadingnumber[0].' '.$sh.'</h3>';
}
$paragraphs = $ss->xpath('b:content');
foreach ($paragraphs as $p){
echo '<p>'.$p.'</p>';
}
$lists = $ss->xpath('c:list');
foreach ($lists as $l){
$listitem = $l->xpath('c:listitem');
foreach ($listitem as $item){
$listcontent = $item->xpath('b:content');
foreach ($listcontent as $a){
echo '<li>'.$a.'</li>';
}
}
}
}
您缺少带有命名空间定义的文档元素。他们是
important,你不应该依赖前缀(它们可以改变并且对于元素是可选的)。
为了这个答案,我添加了一个带有虚拟命名空间的文档元素。
<?xml version="1.0" encoding="utf-8" ?>
<a:content
xmlns:a="urn:a"
xmlns:b="urn:b"
xmlns:c="urn:c"
xmlns:f="urn:f">
<a:section>
...
XSLT 正是用于此目的的模板语言。它允许您为节点定义匹配项并转换它们:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="urn:a"
xmlns:b="urn:b"
xmlns:c="urn:c"
xmlns:f="urn:f"
exclude-result-prefixes="a b c f">
<xsl:output method="html"/>
<xsl:template match="/*">
<div>
<xsl:for-each select="a:section">
<h2><xsl:value-of select="c:title"/></h2>
<xsl:for-each select="f:subsection">
<h3><xsl:value-of select="c:title"/></h3>
<div><xsl:apply-templates select="b:content|c:list"/></div>
</xsl:for-each>
</xsl:for-each>
</div>
</xsl:template>
<xsl:template match="b:content">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="c:list">
<ul>
<xsl:for-each select="c:listitem">
<li><xsl:apply-templates/></li>
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template match="c:url">
<a href="{@type}://{@address}"><xsl:apply-templates/></a>
</xsl:template>
</xsl:stylesheet>
注意匹配您 XML 文档中的命名空间。
PHP 将加载 XML 和模板并对其进行处理:
// load the content
$content = new DOMDocument();
$content->load(__DIR__.'/content.xml');
// load the template
$template = new DOMDocument();
$template->load(__DIR__.'/transform.xsl');
// bootstrap XSLT
$processor = new XSLTProcessor();
$processor->importStylesheet($template);
// transform and output
echo $processor->transformToXml($content);
输出:
<div>
<h2>Title of content</h2>
<h3>Subsection title</h3>
<div>
<p>Make sure you check out this link: <a href="https://www.google.com">google.com</a> and then review the list below:</p>
<ul>
<li><p>bullet item 1</p></li>
<li><p>bullet item 2</p></li>
<li><p>bullet item 3</p></li>
</ul>
<p>More content here in text form</p>
</div>
</div>
我正在尝试解析带有 PHP 命名空间的 XML 文档以输出 HTML,并保留其原始结构。
我在下面的代码中使用了 XPATH 和 foreach 循环来呈现标题、段落和列表,但这不符合文档的原始结构。我也不清楚如何渲染嵌入在内容中的 URL 之类的内容,这些内容也包含在 XML 标签中。
XML 示例:
<a:section>
<c:ref value="1">1</c:ref>
<c:title>Title of content</c:title>
<f:subsection>
<c:ref value="1.1">1.1</c:ref>
<c:title>Subsection title</c:title>
<b:content>Make sure you check out this link: <c:url address="www.google.com" type="https">google.com</c:url> and then review the list below:</b:content>
<c:list type="bullet">
<c:listitem>
<b:content>bullet item 1</b:content>
</c:listitem>
<c:listitem>
<b:content>bullet item 2</b:content>
</c:listitem>
<c:listitem>
<b:content>bullet item 3</b:content>
</c:listitem>
</c:list>
<b:content>More content here in text form</b:content>
</f:subsection>
</a:section>
PHP 示例:
$xml = file_get_contents('content.xml');
$sxml = new SimpleXmlElement($xml);
$section = $sxml->xpath('//a:section');
foreach ($section as $s) {
$sectionnumber = $s->xpath('c:ref');
$title = $s->xpath('c:title');
foreach ($title as $t) {
echo '<h2>'.$sectionnumber[0].' '.$t.'</h2>';
}
}
$subsection = $s->xpath('f:subsection');
foreach ($subsection as $ss) {
$subheadingnumber = $ss->xpath('c:ref');
$subheading = $ss->xpath('c:title');
foreach ($subheading as $sh) {
echo '<h3>'.$subheadingnumber[0].' '.$sh.'</h3>';
}
$paragraphs = $ss->xpath('b:content');
foreach ($paragraphs as $p){
echo '<p>'.$p.'</p>';
}
$lists = $ss->xpath('c:list');
foreach ($lists as $l){
$listitem = $l->xpath('c:listitem');
foreach ($listitem as $item){
$listcontent = $item->xpath('b:content');
foreach ($listcontent as $a){
echo '<li>'.$a.'</li>';
}
}
}
}
您缺少带有命名空间定义的文档元素。他们是 important,你不应该依赖前缀(它们可以改变并且对于元素是可选的)。
为了这个答案,我添加了一个带有虚拟命名空间的文档元素。
<?xml version="1.0" encoding="utf-8" ?>
<a:content
xmlns:a="urn:a"
xmlns:b="urn:b"
xmlns:c="urn:c"
xmlns:f="urn:f">
<a:section>
...
XSLT 正是用于此目的的模板语言。它允许您为节点定义匹配项并转换它们:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="urn:a"
xmlns:b="urn:b"
xmlns:c="urn:c"
xmlns:f="urn:f"
exclude-result-prefixes="a b c f">
<xsl:output method="html"/>
<xsl:template match="/*">
<div>
<xsl:for-each select="a:section">
<h2><xsl:value-of select="c:title"/></h2>
<xsl:for-each select="f:subsection">
<h3><xsl:value-of select="c:title"/></h3>
<div><xsl:apply-templates select="b:content|c:list"/></div>
</xsl:for-each>
</xsl:for-each>
</div>
</xsl:template>
<xsl:template match="b:content">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="c:list">
<ul>
<xsl:for-each select="c:listitem">
<li><xsl:apply-templates/></li>
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template match="c:url">
<a href="{@type}://{@address}"><xsl:apply-templates/></a>
</xsl:template>
</xsl:stylesheet>
注意匹配您 XML 文档中的命名空间。
PHP 将加载 XML 和模板并对其进行处理:
// load the content
$content = new DOMDocument();
$content->load(__DIR__.'/content.xml');
// load the template
$template = new DOMDocument();
$template->load(__DIR__.'/transform.xsl');
// bootstrap XSLT
$processor = new XSLTProcessor();
$processor->importStylesheet($template);
// transform and output
echo $processor->transformToXml($content);
输出:
<div>
<h2>Title of content</h2>
<h3>Subsection title</h3>
<div>
<p>Make sure you check out this link: <a href="https://www.google.com">google.com</a> and then review the list below:</p>
<ul>
<li><p>bullet item 1</p></li>
<li><p>bullet item 2</p></li>
<li><p>bullet item 3</p></li>
</ul>
<p>More content here in text form</p>
</div>
</div>