2009-05-02 15 views
2

Wie kann ich:php XPath - erhalten nur Tag-Attribute/entfernen inneren Tag Inhalt

  1. ausblenden alles zwischen zwischen den Head-Tags in XPath "/ html/head" query?

Zum Beispiel auf „<html><head><title>some title</title>some text</head> ...“ wird nodeValue = „einig Titel etwas Text“ zu produzieren, die irrelevant ist, weil ich die Tag-Attribute nur brauchen, und ich brauche nicht irrelevante Daten zu meiner Datenbank hinzuzufügen.

  1. Alle untergeordneten/untergeordneten Knoten in der xpath "/ html/body" -Abfrage ausblenden?

Zum Beispiel auf „<html><body><div>some anchor</div>some text</body> ...“ zu produzieren nodeValue = „einig Anker some text“ „some text“ an den Body-Tag relevant sind, und ich brauche es zu halten und Fahrt von alles andere zu bekommen.

Auch ich möchte sie nicht aus dem dom-Dokument insgesamt entfernen!

+0

Sie möchten es nicht in Ihrer Datenbank speichern, aber Sie möchten das DOM intakt? WFT? Vielleicht sollten Sie uns sagen, was Sie eigentlich versuchen möchten, da Ihre Frage, wie sie aussieht, wenig Sinn macht? PHP bietet viele Möglichkeiten zur Verwendung von XPath, über den DOM-Reader, über das SimpleXML-Objekt, über XSLT und abhängig von der PHP-Version durch verschiedene Brüharten. Welche verwenden Sie? – AlexanderJohannesen

+0

Weil, wenn es nicht intakt ist, wie lese ich diese childs-Tag, wie ich den Baum später durchqueren. Ich zerlege jedes Tag in alle seine Attribute und Inhalte, aber nicht die damit verbundenen Nachkommen. Das Kopf-Tag ist anders, weil jeder darin platzierte direkte Text ignoriert werden sollte. Wenn ich also eine Funktion habe, die jedes Tag im HTML-Dokument durchläuft, fragt es immer nach allen Tags und Inhalten, außer wenn ich etwas anderes vorschlage. – EddyR

+0

Nun, der Grund, warum ich Sie gefragt habe, was Sie erreichen wollen und welche PHP-Versionen und Umgebung Sie haben, ist, dass dies in XSLT trivial ist, vielleicht sogar einfach genug in SimpleXML, aber bevor ich viel davon vergebe Zeitknirschen wäre es toll mit ein paar Richtungshinweisen. :) – AlexanderJohannesen

Antwort

0

EDIT: Über das Kopfelement - Sie wollen nur die Attribute des Kopfelements erhalten, können Sie XPath ("// head") and then $head->attributes verwenden.

Ich werde nicht direkt auf Ihre Frage antworten, die nicht sehr detailliert ist, aber ich werde eher eine Geschichte über meine eigene Erfahrung erzählen. Ich glaube, dass Sie Ihre Probleme lösen können, wenn Sie die Implikationen der Beispiele verstehen, die ich gebe.

Ich verstehe von den Tags, die Sie PHP bei der Arbeit verwenden möchten. Ich hatte in letzter Zeit ein ähnliches Problem, bei dem ich rund 100 statische HTML-Dokumente analysieren und Teile der Informationen extrahieren musste, um sie in einer Datenbank zu speichern. Anfangs dachte ich über reguläre Ausdrücke nach, aber als ich mitkam, sah ich, dass das eine mühsame Aufgabe sein würde.

Also endete ich mich mit XPath und SimpleXML in PHP.

Hier ist, wie ich am Ende:

$file_contents = file_get_contents($file); 
$dom = new DOMDocument; 
$dom->loadHTML($file_contents); 
$document = simplexml_import_dom($dom); 

Jetzt habe ich ein SimpleXML Objekt, das den HTML-Code enthält. Das ist wirklich toll - hier ist, wie es rollt:

nehme an, Sie den folgenden HTML-Code haben:

<div id="content"> 
<div class="description"> 
    <dl> 
     <dt>Title</dt> 
     <dd> 
      <ul><li> first item </li> <li> second item</li></ul> 
      <p> a paragraph.. </p> 
     </dd> 
    </dl> 
</div> 
</div> 

Jetzt können Sie alle <dl> Elemente im Code durchlaufen, das sind Kinder div # Beschreibung und Enkel von div # content wie folgt aus:

foreach($document->xpath("//div[@id='content']/div[@class='description']/dl") as $element) 

und dann alle Kinder werden durch eine rekursive Funktion wie diese analysiert:

function recurse($parent) 
{ 
echo '<' . $parent->getName() . '>' . "\n"; 
#echo $parent # you might want to strip any white spaces like \t and \n here 

foreach($parent->children() as $child) 
{ 
    if(count($child->children()) > 0) 
    { 
     recurse($child); 
    } 
    else 
    { 
     echo '<' . $child->getName() . '>'; 
     echo $child; 
     echo '</' . $child->getName() . '>' . "\n"; 
    } 
} 
echo '</' . $parent->getName() . '>' . "\n"; 
} 

Ich hoffe, dass ich Ihnen geholfen habe, viel Glück!

+0

edit - Ja, das ist wahr, aber es ist Teil einer Funktion, die die HTML - Baumstruktur durchläuft, was bedeutet, dass sie die Information hinzufügen wird, ob ich will oder nicht, es sei denn, ich spezifiziere jede Art von Tag (Knoten), die ich ignorieren möchte nervt mich :)) – EddyR

1

In diesem Fall könnte ein preg_match wie dieser vielleicht das sein, was Sie brauchen?

preg_match('/<head (.*)>/', $file_contents, $matches); 
echo (isset($matches[1])) ? $matches[1] : ''; 
1

, die irrelevant ist, weil ich brauche nur die Tag-Attribut

Ich bin nicht sicher, wo die Attribute in Ihrem Beispiel sind. Und bin kein PHP XPath Implementierungsexperte.

Allerdings können Sie versuchen, die folgenden:

  • verwenden, um die text() XPath-Funktion am Ende des Ausdrucks (zB "/html/head/text()") nur die Textknoten zu bekommen, keine Tags
  • die XPath-Funktion eine Rückkehr sollte NodeList. Sie sollten das verwenden, um eine vollständige XML-Fragment - z. DOMXpath tut genau das.