我需要在这一段XML中获取answer
的HTML内容:
<qa>
<question>Who are you?</question>
<answer>Who who, <strong>who who</strong>, <em>me</em></answer>
</qa>
所以我希望得到一个字符串“Who who,&lt; strong&gt; who who&lt; / strong&gt;,&lt; em&gt; me&lt; / em&gt;”。
如果我将answer
作为SimpleXMLElement
,我可以致电asXML()
以获取“&lt; answer&gt;谁是谁,&lt; strong&gt;谁&lt; / strong&gt;,&lt; ; em&gt;我&lt; / em&gt;&lt; / answer&gt;“但是如何在没有元素本身的情况下获取元素的内部XML?
我更喜欢不涉及字符串函数的方法,但如果这是唯一的方法,那就这样吧。
答案 0 :(得分:12)
function SimpleXMLElement_innerXML($xml)
{
$innerXML= '';
foreach (dom_import_simplexml($xml)->childNodes as $child)
{
$innerXML .= $child->ownerDocument->saveXML( $child );
}
return $innerXML;
};
答案 1 :(得分:6)
这有效(虽然看起来很蹩脚):
echo (string)$qa->answer;
答案 2 :(得分:5)
据我所知,没有内置的方法来实现这一目标。我建议尝试SimpleDOM,这是一个扩展SimpleXMLElement的PHP类,它为大多数常见问题提供了方便的方法。
include 'SimpleDOM.php';
$qa = simpledom_load_string(
'<qa>
<question>Who are you?</question>
<answer>Who who, <strong>who who</strong>, <em>me</em></answer>
</qa>'
);
echo $qa->answer->innerXML();
否则,我会看到两种方法。第一种方法是将SimpleXMLElement
转换为DOMNode
,然后循环遍历childNodes
以构建XML。另一种方法是调用asXML()
然后使用字符串函数删除根节点。但需要注意的是,asXML()
有时可能会返回实际上从其调用的节点 之外的标记,例如XML prolog或Processing Instructions。
答案 3 :(得分:4)
最直接的解决方案是使用简单的XML实现自定义get innerXML:
function simplexml_innerXML($node)
{
$content="";
foreach($node->children() as $child)
$content .= $child->asXml();
return $content;
}
在您的代码中,将$body_content = $el->asXml();
替换为$body_content = simplexml_innerXML($el);
但是,您也可以切换到另一个API,它可以区分innerXML(您正在寻找的内容)和outerXML(您现在获得的内容)。 Microsoft Dom libary提供了这种区别,但遗憾的是PHP DOM没有。
我发现PHP XMLReader API提供了这种区别。请参阅readInnerXML()。虽然这个API在处理XML方面有很多不同的方法。试试吧。
最后,我要强调的是,XML并不是要将数据提取为子树,而是将其作为值。这就是为什么你在找到合适的API时遇到麻烦的原因。将HTML子树存储为值(并转义所有标记)而不是XML子树将更“标准”。还要注意一些HTML synthax并不总是与XML兼容(即
vs,
)。无论如何,在实践中,你的方法对于编辑xml文件肯定更方便。
答案 4 :(得分:1)
我会扩展SimpleXmlElement类:
class MyXmlElement extends SimpleXMLElement{
final public function innerXML(){
$tag = $this->getName();
$value = $this->__toString();
if('' === $value){
return null;
}
return preg_replace('!<'. $tag .'(?:[^>]*)>(.*)</'. $tag .'>!Ums', '$1', $this->asXml());
}
}
然后像这样使用它:
echo $qa->answer->innerXML();
答案 5 :(得分:0)
<?php
function getInnerXml($xml_text) {
//strip the first element
//check if the strip tag is empty also
$xml_text = trim($xml_text);
$s1 = strpos($xml_text,">");
$s2 = trim(substr($xml_text,0,$s1)); //get the head with ">" and trim (note that string is indexed from 0)
if ($s2[strlen($s2)-1]=="/") //tag is empty
return "";
$s3 = strrpos($xml_text,"<"); //get last closing "<"
return substr($xml_text,$s1+1,$s3-$s1-1);
}
var_dump(getInnerXml("<xml />"));
var_dump(getInnerXml("<xml / >faf < / xml>"));
var_dump(getInnerXml("<xml >< / xml>"));
var_dump(getInnerXml("<xml>faf < / xml>"));
var_dump(getInnerXml("<xml > faf < / xml>"));
?>
在我搜索了一段时间后,我得不到满意的解决方案。所以我写了自己的功能。
此函数将获得innerXml
内容(当然包括空格)。
要使用它,请传递函数asXML()
的结果,如此getInnerXml($e->asXML())
。此函数也适用于具有许多前缀的元素(就我的情况而言,因为我找不到任何在不同前缀的所有子节点上进行转换的当前方法)。
输出:
string '' (length=0)
string '' (length=0)
string '' (length=0)
string 'faf ' (length=4)
string ' faf ' (length=6)
答案 6 :(得分:0)
function get_inner_xml(SimpleXMLElement $SimpleXMLElement)
{
$element_name = $SimpleXMLElement->getName();
$inner_xml = $SimpleXMLElement->asXML();
$inner_xml = str_replace('<'.$element_name.'>', '', $inner_xml);
$inner_xml = str_replace('</'.$element_name.'>', '', $inner_xml);
$inner_xml = trim($inner_xml);
return $inner_xml;
}
答案 7 :(得分:0)
如果您不想剥离CDATA部分,请注释掉第6-8行。
function innerXML($i){
$text=$i->asXML();
$sp=strpos($text,">");
$ep=strrpos($text,"<");
$text=trim(($sp!==false && $sp<=$ep)?substr($text,$sp+1,$ep-$sp-1):'');
$sp=strpos($text,'<![CDATA[');
$ep=strrpos($text,"]]>");
$text=trim(($sp==0 && $ep==strlen($text)-3)?substr($text,$sp+9,-3):$text);
return($text);
}
答案 8 :(得分:0)
您可以使用此功能:)
function innerXML( $node )
{
$name = $node->getName();
return preg_replace( '/((<'.$name.'[^>]*>)|(<\/'.$name.'>))/UD', "", $node->asXML() );
}
答案 9 :(得分:0)
这是我创建的一个非常快速的解决方案:
function InnerHTML($Text)
{
return SubStr($Text, ($PosStart = strpos($Text,'>')+1), strpos($Text,'<',-1)-1-$PosStart);
}
echo InnerHTML($yourXML->qa->answer->asXML());
答案 10 :(得分:-2)
使用正则表达式,你可以这样做
preg_match(’/<answer(.*)?>(.*)?<\/answer>/’, $xml, $match);
$result=$match[0];
print_r($result);