Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Attribute auslesen nicht möglich (https://www.delphipraxis.net/186443-attribute-auslesen-nicht-moeglich.html)

Ajintaro 3. Sep 2015 11:06

Attribute auslesen nicht möglich
 
Hallo DP,

Ich versuche von folgender XML-Struktur einige Attribute auszulesen:

Code:
<testCase
 name="XML_test"
 mood="negative">
   <Actions>
      <Jump>
         <not_expected>
               <debugMessages type="E"/>
               <displayMessages type="E"/>
         </not_expected>
         <force>
            <Fly
               WDS_FROM_PAGE="XXX"
               TEST1="123"
               TEST2="456"/>         
         </force>         
      </Jump>
      <Fly>
         <expected>            
            <LifeMessages type="F" code="IN_HEAVEN" parameterName="DUMMY_PAGE"/>
         </expected>
         <stop/>
      </Fly>
   </Actions>
</testCase>
Ich möchte mittels xpath die Attribute der nodes:

//jump/not_expected/debugMessages in eine Liste schreiben: type="E"
//jump/force/Fly in eine Liste schreiben: WDS_FROM_PAGE="XXX",TEST1="123",TEST2="456"
//Fly/expected/LifeMessages in eine Liste schreiben: type="F",code="IN_HEAVEN",parameterName="xxx"

Gebastelt habe ich folgendes:

Delphi-Quellcode:
{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// cleanup_oxml
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Procedure cleanup_oxml;
begin
 FreeAndNil(FXPathResults);
end;
{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// prepare_oxml
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Procedure prepare_oxml(xml_file:string);
begin
FXMLDocument := CreateXMLDoc;
 FXMLDocument.WriterSettings.IndentType := itIndent;
 if not FXMLDocument.LoadFromFile(xml_file) then
   raise Exception.Create('Source xml document is not valid');
 FXPathResults := TStringList.Create;
end;
{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// xpath_oxml (uses OXmlPDOM, OXmlUtils)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Procedure xpath_oxml(xml_file,expression:string;amemo:Tmemo;mode:integer);
Var
  expressionList: string;
  iNode        : integer;
  nodeList     : IXMLNodeList;
  p            : integer;
  queryNode    : PXMLNode;
  validResult  : boolean;
  Attribute    : PXMLNode;
  ForceNode    : PXMLNode;
  ForceTarget  : PXMLNode;
begin
 try
  prepare_oxml(xml_file);
  queryNode := FXMLDocument.DocumentElement;
  expressionList := expression;
  amemo.Clear;
 repeat
    p := Pos('+', expressionList);
    if p > 0 then
    begin
      expression := TrimRight(Copy(expressionList, 1, p-1));
      Delete(expressionList, 1, p);
      expressionList := TrimLeft(expressionList);
    end
    else
     expression := expressionList;
     nodeList := queryNode.SelectNodes(expression);
     ForceNode := queryNode.SelectNode(expression);
    if nodeList.Count > 0 then
      queryNode := nodeList[0]
    else
      queryNode := nil;
  until p = 0;

  if mode = 2 then
  begin
    //iterate through all attributes -> you MUST set the node to nil
    Attribute := nil;
    //showmessage(ForceNode.NodeName);
    if ForceNode.HasChildNodes then
    begin
      showmessage(ForceNode.NodeName +' has ChildNodes');
      ForceTarget := ForceNode.NextSibling;
      Showmessage(ForceTarget.NodeName);
    end;


    while ForceNode.GetNextAttribute(Attribute) do
    amemo.Lines.Add(ForceNode.NodeName+'['+
      Attribute.NodeName+'] = '+
      Attribute.NodeValue);
  end;


  for iNode := 0 to nodeList.Count-1 do
  begin
    if mode = 0 then amemo.Lines.Add(nodeList[iNode].XML);
    if mode = 1 then amemo.Lines.Add(nodeList[iNode].NodeName);
  end;


 finally
   cleanup_oxml;
 end;
end;
Ich habe mit oxml experimentiert und wollte eine Funktion erstellen, die mir je nach Modus das gewünschte Ergebnis liefert. Hier 3 Beispiel-Aufrufe:

(1)
Delphi-Quellcode:
xpath_oxml(testcase_filename,'//force',memo_tc,0);
(mode 0) ergibt:

Code:
<force>
  <Fly WDS_FROM_PAGE="XXX" TEST1="123" TEST2="456"/>
</force>
Fly
(2)
Delphi-Quellcode:
xpath_oxml(testcase_filename,'//force',memo_tc,1);
(mode 1) ergibt:

Code:
force
Fly
(3)
Delphi-Quellcode:
xpath_oxml(testcase_filename,'//force',memo_tc,2);
(mode 2)

sollte mir die Attribute liefern, aber meine ForceNode hat angeblich keine ChildNode und somit komme ich nicht an die Attribute heran.
Kann man dass auch einfacher (ohne oxml) lösen?

Der schöne Günther 3. Sep 2015 11:21

AW: Attribute auslesen nicht möglich
 
Ich bin in XML, insbesondere XPath, nicht wirklich fit. Ich hatte mir einmal einen TXPathHelper gebaut: http://www.delphipraxis.net/1236534-post4.html

Damit kommt man an folgendes Ergebnis:
Code:
Attributes of /.//Jump/not_expected/debugMessages:
type = E

Attributes of /.//Jump/force/Fly:
WDS_FROM_PAGE = XXX
TEST1 = 123
TEST2 = 456

Attributes of /.//Fly/expected/LifeMessages:
type = F
code = IN_HEAVEN
parameterName = DUMMY_PAGE
Mit folgendem Code:
Delphi-Quellcode:
procedure justXmlThings();
const
   paths: TArray<String> = [
      '/.//Jump/not_expected/debugMessages',
      '/.//Jump/force/Fly',
      '/.//Fly/expected/LifeMessages'
   ];
var
   xmlDoc: IXMLDocument;
   path: String;
   node: IXmlNode;
begin
   xmlDoc := LoadXMLData(content);

   for path in paths do begin
      node := TXpathHelper.SelectNode(xmlDoc.Node, path);
      if Assigned(node) then begin
         WriteLn('Attributes of ', path,':');
         printAttributes(node);
         WriteLn(sLineBreak);
      end;
   end;
end;

procedure printAttributes(ofNode: IXMLNode);
var
   attributeIndex:   Integer;
   attribute:      IXMLNode;
begin
   for attributeIndex := 0 to Pred(ofNode.AttributeNodes.Count) do begin
      attribute := ofNode.AttributeNodes.Get(attributeIndex);
      WriteLn(attribute.NodeName, ' = ', attribute.NodeValue);
   end;
end;
Nur musst du dann auch auf Groß- und Kleinschreibung achten! Du hattest "Jump" klein geschrieben.

Ajintaro 3. Sep 2015 14:04

AW: Attribute auslesen nicht möglich
 
Hallo Günther,

Ich habe mir den Code angesehen und bin erstaunt, Xpathhelper ist eine tolle Hilfe!

Vielen Dank für die Unterstützung!! :dp:


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz