我需要得到answer的HTML内容在此位XML的:

<qa>
 <question>Who are you?</question>
 <answer>Who who, <strong>who who</strong>, <em>me</em></answer>
</qa>

所以,我想要得到的字符串 “谁是谁,谁谁的。”

如果我有answer作为SimpleXMLElement,我可以打电话asXML()得到 “<答案>谁是谁,谁谁”,但如何获得的元件的内XML的周围没有包裹元件本身?

我宁愿不涉及字符串函数的方式,但如果这是唯一的办法,就这样吧。

有帮助吗?

解决方案

据我所知,目前没有内置的方式来获取。我建议尝试 SimpleDOM ,这是提供了最方便的方法PHP类扩展的SimpleXMLElement的常见问题。

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构建XML转换为childNodes然后循环。其他将调用asXML()然后使用字符串函数以除去根节点。注意虽然,asXML()有时返回标记,实际上是 的节点的它是从调用,如XML序言或处理指令之外。

其他提示

function SimpleXMLElement_innerXML($xml)
  {
    $innerXML= '';
    foreach (dom_import_simplexml($xml)->childNodes as $child)
    {
        $innerXML .= $child->ownerDocument->saveXML( $child );
    }
    return $innerXML;
  };

这工作(尽管它似乎真的跛脚):

echo (string)$qa->answer;

最直接的解决方案是实现自定义得到innerXML用简单的XML:

function simplexml_innerXML($node)
{
    $content="";
    foreach($node->children() as $child)
        $content .= $child->asXml();
    return $content;
}

在您的代码,替换$body_content = $el->asXml(); $body_content = simplexml_innerXML($el);

不过,您也可以切换到提供和outerXML(你会得到什么现在)innerXML区分(你在找什么)另一个API。微软大教堂libary提供这一区分,但是不幸的是PHP DOM没有。

我发现PHP的XMLReader API提供了这种distintion。见readInnerXML()。虽然这个API有相当不同的方法来处理XML。尝试。

最后,我想强调的是,XML不意味着提取的数据作为子树而是作为值。这就是为什么你运行陷入困境找到合适的API。这将是更“标准”来存储HTML子树的值(和逃避所有标签),而不是XML树。另外注意的是一些HTML synthax并不总是XML兼容(即点击VS,搜索)。在实践中,无论如何,你的做法是绝对是编辑XML文件更加方便。

我将具有延长的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();
<?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)
    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;
    }

如果你不想要去除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);
}

您可以只使用此功能:)

function innerXML( $node )
{
    $name = $node->getName();
    return preg_replace( '/((<'.$name.'[^>]*>)|(<\/'.$name.'>))/UD', "", $node->asXML() );
}

使用正则表达式,你可以做到这一点。

preg_match(’/<answer(.*)?>(.*)?<\/answer>/’, $xml, $match);
$result=$match[0];
print_r($result);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top