Xpath von Child auf Parent zugreifen und ID ausgeben

BIM-T

Mitglied
Hallo ich möchte über ein Child-Element auf das zugehörige Eltern-Element zugreifen. Leider komme ich mit meinem Xpath-Pfad in meinem DOM nicht ans Ziel.
Kann mir irgendwer mit der Rückwärtsnavigation behilflich sein?

Ganz Konkret möchte ich in dem folgenden XML-Schnipsel von der <IfcOwnerHistory xsi:nil="true" ref="i1677"/> auf das Eltern-Element <IfcPropertySet id="i2032"> springen und mir die zugehörige ID ausgeben lassen.
XML:
<IfcPropertySet id="i2032">
<GlobalId>3lRJNnzSXDfv7i5MWTyhvp</GlobalId>
<OwnerHistory id="33">
<IfcOwnerHistory xsi:nil="true" ref="i1677"/>
</OwnerHistory>
<Name>Pset_WallCommon</Name>
<HasProperties exp:cType="set">
<IfcPropertySingleValue xsi:nil="true" ref="i1935"/>
<IfcPropertySingleValue xsi:nil="true" ref="i1936"/>
<IfcPropertySingleValue xsi:nil="true" ref="i1937"/>
<IfcPropertySingleValue xsi:nil="true" ref="i1938"/>
<IfcPropertySingleValue xsi:nil="true" ref="i2031"/>
</HasProperties>
</IfcPropertySet>

Hier mein aktueller Pfad im DOM
PHP-Code:
PHP:
$get_all_Pset_IDs = $xpath->query("//parent::ifc:IfcPropertySet/ifc:OwnerHistory/ifc:IfcOwnerHistory[@ref='i1677']/@id");
Leider Funktioniert es weder mit ancestor:: noch anders, oder ich mache etwas falsch.

Würde mich freuen wenn mir jemand Hilfestellung geben könnte.
 
Ah, diesen Thread hatte ich gar nicht gesehen! Ich finde diesen Beitrag wunderbar: enthält einen kleinen relevanten XML-Auszug mit einer klaren Fragestellung einem Eigenversuch.

Lies zuerst meinen Beitrag im anderen Thread, dann probier folgendes Query, was in Angesicht deines neuen Beispiels spezifischer als das Query im meinem anderen Beitrag ist:

Code:
//ifc:IfcPropertySingleValue[@ref="i1677"]/ancestor::IfcPropertySet[@id][1]
 
Hallo, vielen Dank für deine Unterstützung ich habe jetzt eben mal das Versucht was du mir freundlicher weise erläutert hast. Leider funktioniert meine Abfrage noch nicht! :-(
Ich Versuche trotzdem mal zu erläutern was ich "verstanden" habe:

PHP:
 $get_all_Pset_IDs = $xpath->query('//ifc:IfcOwnerHistory[@ref="i1677"]/ancestor::ifc:OwnerHistory/ancestor::ifc:IfcPropertySet[@id][1]');
   
    $Test_IDs[]= $get_all_Pset_IDs->nodeValue;  

        var_dump($Test_IDs);

mit:
PHP:
'//ifc:IfcOwnerHistory[@ref="i1677"]
Suche ich erstmal das Kindelement.

Da ifcOwnerHistory ein Kind von OwnerHistory ist und OwnerHistory wiederum eines von PropertySet navigiere ich dann hoch bis zum Parent PropertySet.
Ist das soweit richtig?
PHP:
/ancestor::ifc:OwnerHistory/ancestor::ifc:IfcPropertySet[@id][1]

Warum steht @id hierbei in []-Klammern und wofür benötige ich die [1|?
bei meiner anderen Abfrage habe ich es so gemacht:
PHP:
$get_all_Walls = $xpath->query('//*/ifc:IfcWallStandardCase/@id');

Vielen Dank für die Hilfe
 
Hallo Guten Morgen, ich glaube ich habe es herausgefunden :)

Zumindest liefert es die korrekten werte.
PHP:
 $get_all_Pset_IDs = $xpath->query('//ifc:IfcPropertySet/ifc:OwnerHistory/ifc:IfcOwnerHistory[@ref="i1677"]/ancestor::ifc:IfcPropertySet/@id');

Ist das korrekt oder birgt die Abfrage irgendwelche Fallstricke die anders Formuliert werden sollten?
 
Da ifcOwnerHistory ein Kind von OwnerHistory ist und OwnerHistory wiederum eines von PropertySet navigiere ich dann hoch bis zum Parent PropertySet.
Ist das soweit richtig?
Ja genau!

Dein erstes Query sieht mir schon richtig aus, aber gut, dass du ein anderes funktionierendes gefunden hat.
$Test_IDs[]= $get_all_Pset_IDs->nodeValue;

Möglicherweise war diese Zeile das Problem. Es kann sein, dass du eine DOMNodeList zurückbekommst, die kein nodeValue hat -- weil eben erstmal eine Liste.

Warum steht @id hierbei in []-Klammern und wofür benötige ich die [1|?
Wenn du allgemein "//blah/blub[...]" hast, dann matcht das nur "//blah/blub", wenn auch die Bedingung ... erfüllt ist. Die Bedingung "@id" bedeutet, dass es ein Attribut namens id hat -- egal mit welchem Wert, nur die Existenz wird geprüft. Die [1] wählt das erste Ergebnis aus, weil ancestor eben auf ggf. alle möglichen (!) Vorfahren bis hin zur Wurzel matchen könnte.

Folgendes Query sollte noch einfacher sein:
Code:
//ifc:IfcOwnerHistory[@ref="i1677"]/ancestor::ifc:IfcPropertySet/@id

Beachte, dass wenn du folgendes XML hättest,
XML:
<IfcPropertySet id="foo">
  <IfcPropertySet id="bar">
    <dinosaurier>
      <IfcOwnerHistory ref="i1677" />
    </dinosaurier>
  </IfcPropertySet>
</IfcPropertySet>

dass du dann sowohl "foo" als auch "bar" zurückbekommst! Falls du nur die innerste IfcPropertySet id möchtest, würde ich
Code:
//ifc:IfcOwnerHistory[@ref="i1677"]/ancestor::ifc:IfcPropertySet[1]/@id
probieren. Das sucht nämlich alle IfcPropretySet Vorfahren, wählt nur den ersten mittels [1] aus und gibt dann seine id zurück.
 
Zurück