我想要在HTML中转换一个复杂的XML。某些标签需要在html标签中替换。
XML就是这样:
<root>
<div>
<p>
<em>bol text</em>, some normale text
</p>
</div>
<list>
<listitem>
normal text inside list <em>bold inside list</em>
</listitem>
<listitem>
another text in list...
</listitem>
</list>
<p>
A sample paragraph
</p>
元素内的文本是可变的,这意味着我解析的另一个xml可以完全改变。
我想要的输出是这个(对于这种情况):
<root>
<div>
<p>
<strong>bol text</strong>, some normale text
</p>
</div>
<ul>
<li>
normal text inside list <strong>bold inside list</strong>
</li>
<li>
another text in list...
</li>
</ul>
<p>
A sample paragraph
</p>
</root>
我创建了一个递归函数来解析xml的任何单个节点并将其替换为HTML标记(但不起作用):
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->load('section.xml');
echo $doc->saveHTML();
function printHtml(DOMNode $node)
{
if ($node->hasChildNodes())
{
foreach ($node->childNodes as $child)
{
printHtml($child);
}
}
if ($node->nodeName == 'em')
{
$newNode = $node->ownerDocument->createElement('strong', $node->nodeValue);
$node->parentNode->replaceChild($newNode, $node);
}
if ($node->nodeName == 'listitem')
{
$newNode = $node->ownerDocument->createElement('li', $node->nodeValue);
$node->parentNode->replaceChild($newNode, $node);
}
}
任何人都可以帮助我吗? 提前谢谢。
这是一个完整的xml的例子:
<root>
<div>
<p>
<em>bol text</em>, some normale text
</p>
</div>
<list>
<listitem>
normal text inside list <em>bold inside list</em>
</listitem>
<listitem>
another text in list...
</listitem>
</list>
<media>
<info isVisible="false">
<title>
<p>Image title <em>in bold</em> not in bold</p>
</title>
</info>
<file isVisible="true">
<href>
"path/to/file.jpg"
</href>
</file>
</media>
<p>
A sample paragraph
</p>
</root>
必须转变:
<root>
<div>
<p>
<strong>bol text</strong>, some normale text
</p>
</div>
<ul>
<li>
normal text inside list <em>bold inside list</em>
</li>
<li>
another text in list...
</li>
</ul>
<!-- the media tag can be presented in two mode: with title visible, and title hidden -->
<!-- this is the case when the title is hidden -->
<img src="path/to/file.jpg" />
<!-- this is the case when the title is visible -->
<!-- the info tag (inside media tag) has an attribute isVisible="false" which means it doesn't have to be shown. -->
<!-- if the info tag has visible=true, the media tag must be transated into
<div>
<img src="path/to/file.jpg" />
<p>Image title <strong>in bold</strong> not in bold</p>
<div>
-->
<p>
A sample paragraph
</p>
</root>
答案 0 :(得分:0)
嗯,也许,这不是最正确的想法,但为什么不只是使用str_replace?这样您就可以清楚地看到要应用的更改列表,并轻松添加/删除新更改。
$file = file_get_contents('file.xml');
$file = str_replace("<em>", "<strong>", $file);
file_put_contents('file.html', $file);
更新(关于问题变更的更多想法)
这里使用PHP + DOM似乎有点棘手(至少对我而言)。也许,使用XSL / XSLT(可扩展样式表语言转换)会更合理。在那种情况下,smth。类似的内容可以在这里找到:How to replace a node-name with another in Xslt?
XSLT专门用于语言转换 http://en.wikipedia.org/wiki/XSLT
答案 1 :(得分:0)
有一种专门为此任务设计的语言:它称为XSLT,您可以在XSLT中轻松表达所需的转换并从PHP程序中调用它。当然,这是一条学习曲线,但它比编写低级DOM代码要好得多。
在XSLT中,您编写了一组模板规则,说明应如何处理各个元素。示例中的许多元素都是未更改的,因此您可以从执行此操作的默认规则开始:
<xsl:template match="*">
<xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>
“匹配”部分说明您要匹配的输入部分;规则的主体说明要产生什么输出。 xsl:apply-templates执行递归下降来处理当前元素的子元素。
您可以简单地重命名某些元素,例如
<xsl:template match="listitem">
<li><xsl:apply-templates/></li>
</xsl:template>
有些规则稍微复杂一些,但仍然很容易表达:
<xsl:tempate match="media/file[@isVisible='true']">
<img src="{href}"/>
</xsl:template>
我希望您同意这种基于声明规则的方法比您的程序代码更清晰;在六个月的时间内,其他人也更容易改变规则。