鉴于php代码:
$xml = <<<EOF
<articles>
<article>
This is a link
<link>Title</link>
with some text following it.
</article>
</articles>
EOF;
function traverse($xml) {
$result = "";
foreach($xml->children() as $x) {
if ($x->count()) {
$result .= traverse($x);
}
else {
$result .= $x;
}
}
return $result;
}
$parser = new SimpleXMLElement($xml);
traverse($parser);
我期望函数traverse()返回:
This is a link Title with some text following it.
但是,它仅返回:
Title
有没有办法使用simpleXML获得预期的结果(显然是为了消耗数据而不是像在这个简单的例子中那样返回它)?
谢谢, Ñ
答案 0 :(得分:17)
有些方法可以通过SimpleXML实现您想要的功能,但在这种情况下,最简单的方法是使用DOM。好消息是,如果您已经在使用SimpleXML,则不需要更改任何内容,因为DOM和SimpleXML是basically interchangeable:
// either
$articles = simplexml_load_string($xml);
echo dom_import_simplexml($articles)->textContent;
// or
$dom = new DOMDocument;
$dom->loadXML($xml);
echo $dom->documentElement->textContent;
假设您的任务是迭代每个<article/>
并获取其内容,您的代码将如下所示
$articles = simplexml_load_string($xml);
foreach ($articles->article as $article)
{
$articleText = dom_import_simplexml($article)->textContent;
}
答案 1 :(得分:4)
node->asXML();// It's the simple solution i think !!
答案 2 :(得分:3)
因此,我的问题的简单答案是:Simplexml无法处理这种XML。请改用DomDocument。
此示例显示如何遍历整个XML。似乎DomDocument可以使用任何XML,而SimpleXML要求XML很简单。
function attrs($list) {
$result = "";
foreach ($list as $attr) {
$result .= " $attr->name='$attr->value'";
}
return $result;
}
function parseTree($xml) {
$result = "";
foreach ($xml->childNodes AS $item) {
if ($item->nodeType == 1) {
$result .= "<$item->nodeName" . attrs($item->attributes) . ">" . parseTree($item) . "</$item->nodeName>";
}
else {
$result .= $item->nodeValue;
}
}
return $result;
}
$xmlDoc = new DOMDocument();
$xmlDoc->loadXML($xml);
print parseTree($xmlDoc->documentElement);
您还可以使用simpleXML加载xml,然后使用dom_import_simplexml()将其转换为DOM,如Josh所说。如果您使用simpleXml过滤节点进行解析,这将非常有用,例如:使用XPath。
但是,我实际上并没有使用simpleXML,所以对我而言,这需要很长时间。
$simpleXml = new SimpleXMLElement($xml);
$xmlDom = dom_import_simplexml($simpleXml);
print parseTree($xmlDom);
感谢您的帮助!
答案 3 :(得分:1)
只需将字符串视为字符串,就可以获得带有simplexml的DOM元素的文本节点:
foreach($xml->children() as $x) {
$result .= "$x"
然而,打印出来:
This is a link
with some text following it.
TitleTitle
..因为文本节点被视为一个块,并且无法分辨子项在文本节点内的位置。由于其他{},子节点也会被添加两次,但您可以将其取出。
很抱歉,如果我没有帮助,但我认为没有办法找出子节点在文本节点中的位置,除非xml是一致的(但是,为什么不使用标签)。如果您知道要删除文本的元素,strip_tags()
将会很有效。
答案 4 :(得分:1)
这已经得到了解答,但是CASTING TO STRING(即$ sString =(string)oSimpleXMLNode-&gt; TagName)总是对我有效。
答案 5 :(得分:0)
就像@tandu所说,这是不可能的,但是如果你可以修改你的XML,这将有效:
$xml = <<<EOF
<articles>
<article>
This is a link
</article>
<link>Title</link>
<article>
with some text following it.
</article>
</articles>
答案 6 :(得分:0)
试试这个:
$parser = new SimpleXMLElement($xml);
echo strip_tags($parser->asXML());
这几乎相当于:
$parser = simplexml_load_string($xml);
echo dom_import_simplexml($parser)->textContent;