Domanda

Ho bisogno di ottenere il contenuto HTML di answer in questo po 'di XML:

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

Quindi voglio ottenere la stringa "Chi che, che che , me ".

Se ho la answer come SimpleXMLElement, posso chiamare asXML() per ottenere " Chi che, che che , me ", ma come ottenere il XML interna di un elemento senza l'elemento in sé avvolto attorno ad esso?

Io preferirei modi che non comportano funzioni di stringa, ma se questo è l'unico modo, così sia.

È stato utile?

Soluzione

Per quanto a mia conoscenza, non v'è built-in modo per ottenere questo. Mi piacerebbe consigliamo di provare SimpleDOM , che è una classe PHP che si estende SimpleXMLElement che offre metodi di convenienza per la maggior parte dei problemi comuni.

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

In caso contrario, vedo due modi per farlo. Il primo sarebbe quello di convertire il vostro SimpleXMLElement ad un DOMNode poi ciclo sulla sua childNodes per costruire il codice XML. L'altro sarebbe chiamare asXML() quindi utilizzare le funzioni di stringa per rimuovere il nodo radice. Attenzione, però, a volte può tornare asXML() markup che in realtà è fuori del nodo è stato chiamato da, come prologo o consigli d'uso di XML.

Altri suggerimenti

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

Questo funziona (anche se sembra davvero zoppo):

echo (string)$qa->answer;

soluzione più semplice è quella di implementare personalizzato ottenere InnerXml con semplice XML:

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

Nel codice, sostituire $body_content = $el->asXml(); con $body_content = simplexml_innerXML($el);

Tuttavia, si potrebbe anche passare a un altro API che offre distinzione tra InnerXml (quello che stai cercando) e OuterXml (quello che si ottiene per ora). Microsoft Dom libary offre questa distinzione, ma purtroppo PHP DOM non lo fa.

ho scoperto che PHP XMLReader API offre questo distintion. Vedere ReadInnerXml (). Anche se questa API ha un approccio molto diverso per l'elaborazione XML. Provatelo.

Infine, vorrei sottolineare che XML non è destinato per estrarre i dati come sottostrutture, ma piuttosto come valore. Ecco perché si incorrere in problemi a trovare l'API destra. Sarebbe più 'standard' per memorizzare HTML sottostruttura come un valore (e la fuga tutti i tag), piuttosto che sotto-albero XML. Inoltre fate attenzione che alcuni synthax HTML non sono sempre compatibili XML (cioè
vs,
). Ad ogni modo, in pratica, ci si avvicina è sicuramente più conveniente per la modifica del file xml.

avrei estendere la classe 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());
    }
}

e quindi utilizzarlo in questo modo:

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

Dopo la ricerca di un po ', ho ricevuto alcuna soluzione di soddisfazione. Così ho scritto la mia propria funzione. Questa funzione otterrà esattamente il contenuto innerXml (tra cui bianco-spazio, naturalmente). Per utilizzarlo, passare il risultato della funzione asXML(), come questo getInnerXml($e->asXML()). Questo lavoro di funzione per gli elementi con molti prefissi così (come il mio caso, come non ho potuto trovare nessuna metodi attuali che fanno la conversione su tutti i nodi figlio di diversi prefissi).

Output:

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

Se non si vuole mettere a nudo sezione CDATA, commentare le linee 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);
}

Si può semplicemente utilizzare questa funzione:)

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

utilizzando regex si potrebbe fare questo

preg_match(’/<answer(.*)?>(.*)?<\/answer>/’, $xml, $match);
$result=$match[0];
print_r($result);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top