Frage

Ich brauche die HTML-Inhalte von answer in diesem Bit von XML zu erhalten:

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

Also ich möchte die Zeichenfolge bekommen "Wer ist wer, , die die , me ".

Wenn ich die answer als SimpleXMLElement haben, kann ich asXML() nennen zu bekommen " Wer ist wer, , die die , me ", aber wie ohne das Element der inneren XML eines Elements erhalten sich um ihn herum gewickelt?

Ich würde es vorziehen, Wege, die String-Funktionen nicht beteiligt ist, aber wenn das der einzige Weg ist, es so sein.

War es hilfreich?

Lösung

Nach bestem Wissen und Gewissen, ist es nicht integrierte Möglichkeit, das zu bekommen. Ich würde empfehlen daher, SimpleDOM , die eine PHP-Klasse ist SimpleXMLElement erstreckt, dass Angebote Komfortmethoden für die meisten der häufigsten Probleme.

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();

Ansonsten sehe ich zwei Möglichkeiten, das zu tun. Die erste wäre Ihre SimpleXMLElement zu einem DOMNode dann Schleife über seine childNodes konvertieren die XML zu bauen. Die andere wäre asXML() rufen dann String-Funktionen verwenden, um den Wurzelknoten zu entfernen. Achtung aber asXML() kann manchmal zurückgeben Markup, das eigentlich ist außerhalb des Knotens aus, wie XML-Prolog oder Verarbeitungshinweise genannt wurde.

Andere Tipps

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

Das funktioniert (obwohl es scheint wirklich lahm):

echo (string)$qa->answer;

einfachste Lösung ist InnerXml mit einfachen XML zu implementieren benutzerdefinierten bekommen:

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

Sie in Ihrem Code ersetzen $body_content = $el->asXml(); mit $body_content = simplexml_innerXML($el);

Allerdings könnte man auch auf eine andere API wechseln die Angebote Unterscheidung zwischen InnerXml (was Sie suchen) und OuterXml (was Sie bekommen). Microsoft Dom libary bietet diese Unterscheidung aber leider PHP DOM nicht.

fand ich, dass PHP XMLReader API dieses distintion bietet. Siehe readInnerXML (). Obwohl diese API hat einen ganz anderen Ansatz zur Verarbeitung von XML. Probieren Sie es aus.

Abschließend möchte ich betonen, dass XML nicht zu extrahieren Daten als Teilstrukturen gemeint, sondern als Wert. Deshalb sollten Sie in Schwierigkeiten läuft das richtige API zu finden. Es wäre mehr ‚Standard‘ zum Speichern von HTML subtree als Wert (und die Flucht Alle Tags) als XML-Teilstruktur. Auch hüte dich, dass einige HTML Synthax sind nicht immer XML kompatibel (d
vs,
). Auf jeden Fall in der Praxis nähern Sie sind auf jeden Fall bequemer für die Bearbeitung der XML-Datei.

Ich würde die SimpleXMLElement Klasse erweitern:

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());
    }
}

und dann verwenden, wie folgt aus:

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>"));      
?>

Nachdem ich für eine Weile suchen, bekam ich keine satisfy Lösung. Also schrieb ich meine eigene Funktion. Diese Funktion erhält exakt den innerXml Inhalt (einschließlich white-space, natürlich). Um es zu verwenden, übergeben Sie das Ergebnis der Funktion asXML(), wie diese getInnerXml($e->asXML()). Diese Funktion Arbeit für Elemente mit vielen Präfixen als auch (wie mein Fall, da ich keine aktuellen Methoden finden konnte, die für alle untergeordneten Knoten verschiedenen Präfixe Umwandlung tun).

Ausgabe:

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;
    }

Wenn Sie nicht wollen, CDATA-Abschnitt abzustreifen, den Kommentar aus Linien 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);
}

Sie können nur mit dieser Funktion:)

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

regex Sie könnten diese

tun
preg_match(’/<answer(.*)?>(.*)?<\/answer>/’, $xml, $match);
$result=$match[0];
print_r($result);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top