Thema: Delphi RDF auslesen

Einzelnen Beitrag anzeigen

MathiasSimmack
(Gast)

n/a Beiträge
 
#9

Re: RDF auslesen

  Alt 14. Feb 2004, 15:59
@Jens: Das, was du hier machst
Delphi-Quellcode:
xmlTopics := xmlDoc.DefaultInterface.documentElement.childNodes;
For iCnt := 0 to xmlTopics.length-1 do
  { ... }
entspricht meiner Ansicht nach der Idee, die Chris am Anfang hatte. Du gehst damit zwar dem Namespace-Problem aus dem Weg und kannst (wenn du es eingrenzt) alle "item"-Knoten bzw. alle "title" auslesen, aber dazu musst du eben alles selbst durchlaufen.

Einer der Vorteile, die bspw. der MS-XML-Parser bietet (nicht nur der, denke ich!), ist aber XPath. Das heißt, du kannst angeben, welche Bedingungen erfüllt sein müssen, und dann erhältst du eine Liste mit allen gefundenen Knoten, die diesen Bedingungen entsprechen. Vielleicht könnte man das (wenn man es nicht allzu wörtlich nimmt) mit dem SELECT-Statement von mySQL vergleichen?!

Im Prinzip macht diese Anweisung:
Delphi-Quellcode:
xmlTopics := xmldoc.selectNodes('//item/title');
if(xmlTopics.length > 0) then
  for i := 0 to xmlTopics.length - 1 do
    lbTopics.Items.Add(xmlTopics.item[i].text);
das gleiche wie
Delphi-Quellcode:
xmlTopics := xmldoc.documentElement.childNodes;
if(xmlTopics.length > 0) then
  for i := 0 to xmlTopics.length - 1 do
    if(xmlTopics.item[i].Get_nodeName = 'item') then
      lbTopics.Items.Add(xmlTopics.item[i].childNodes.item[0].text);
wobei die zweite Variante einen Schönheitsfehler hat: ohne Prüfung wird grundsätzlich der erste Unterknoten benutzt
xmlTopics[i].childNodes.item[0] in der Hoffnung, dass dieser der "title" ist. Normalerweise müsste man also noch prüfen, ob das auch zutrifft, und erst dann könnte/dürfte man die ermittelte Beschreibung in die Listbox eintragen.

Da ist der Weg mit XPath doch weitaus kürzer, weil bei ihm sofort die "title"-Knoten ermittelt werden, die sich unter einem "item"-Knoten befinden.

Oder nimm den Teil, bei dem die URL ermittelt werden soll. Als Referenz (zum Vergleich) dient der Titel (= die Beschreibung) aus der Listbox. Mit einer Schleife müsstest du also wieder durch alle Knoten durch, schauen ob es ein "item"-Knoten ist, prüfen ob der einen untergeordneten "title"-Knoten hat, vergleichen ob dessen Textinhalt mit dem selektierten Eintrag der Listbox identisch ist, und dann zu guter Letzt den "link"-Knoten und damit die URL ermitteln. Bei XPath genügt ein simples:
Delphi-Quellcode:
node := xmldoc.selectSingleNode('//item[title="' +
  lbTopics.Items[lbTopics.ItemIndex] +
  '"]/link');

if(node <> nil) then
  ShowMessage(node.text);
und du hast die URL.

Ein bisschen merkwürdig wird es in diesem speziellen Fall eben nur durch den Namespace. Im PSDK heißt es:
SelectionNamespaces Property (Remarks)
When an XML document contains elements defined in an external namespace, you must use this property to specify that namespace in order to use DOM methods such as selectNodes or selectSingleNode to navigate the document.


@all: Ich habe durch wildes Herumprobieren folgende Variante, die unabhängig vom Namespace trotzdem alle Titel ausliest:
xmlTopics := xmldoc.selectNodes('//*[name(.)="item"]/*[name(.)="title"]'); Etwas ... *hüstel* ... extrem wird´s beim Versuch, die URL zu ermitteln.
Delphi-Quellcode:
node := xmldoc.selectSingleNode(
  { alle Knoten namens "item" }
  '//*[name(.)="item"]/' +
  { alle Unterknoten namens "text", deren Text
    mit dem Listbox-Eintrag identisch ist }

  '*[name(.)="title" and text()="' + lbTopics.Items[lbTopics.ItemIndex] + '"]' +
  { dann eine Ebene nach oben und alle (hoffentlich nur einen!)
    Knoten namens "link" }

  '/../*[name(.)="link"]');

if(node <> nil) then
  ShowMessage(node.text);


Ich bezweifle, dass das eine vernünftige Variante ist. Dann sollte man sich wohl lieber mit dem Namespace auseinander setzen. Aber es funktioniert ... irgendwie ...
  Mit Zitat antworten Zitat