Jump to content
Developer Wiki and Function Reference Links ×

XML elements <> attribrutes


Recommended Posts

Hi,

I have an issue with this example when I use attributes on the element AFTER callout.

source: http://developer.vectorworks.net/index.php?title=VS:GetFirstChild

PROCEDURE Example;
CONST
  userFolder = 12;
  xmlFile = 'Plug-Ins\Common\Data\Preferences.xml';
  xmlRoot = '/Preferences/Callout';
VAR
  xmlID :LONGINT;
  value :STRING;
  elementPath :STRING;

PROCEDURE ShowPathAndValue(path :STRING);
BEGIN
  IF GetElementValue(xmlID, path, value) = 0 THEN BEGIN
     AlrtDialog(Concat(path, Chr(13), value));
  END ELSE BEGIN
     AlrtDialog(Concat('Problem in GetElementValue.', Chr(13), 'Path = ', path));
  END;
END;

BEGIN
  xmlID := InitXML;
  IF ReadXMLFile(xmlID, userFolder, xmlFile) = 0 THEN BEGIN
     IF GetFirstChild(xmlID, xmlRoot, elementPath) = 0 THEN BEGIN
        ShowPathAndValue(Concat(xmlRoot, '/', elementPath));
        WHILE GetPreviousElement(xmlID, Concat(xmlRoot, '/', elementPath), elementPath) = 0 DO BEGIN
           ShowPathAndValue(Concat(xmlRoot, '/', elementPath));
        END;
     END ELSE BEGIN
        AlrtDialog('Problem in GetFirstChild');
     END;
  END ELSE BEGIN
     AlrtDialog('Problem in ReadXMLFile');
  END;
  xmlID := ReleaseXML(xmlID);
END;
RUN(Example);

Normaly it finds each element because they are unique, but when they are the same with different attributes it can only find it once..


=> returns the 2 elements


=> returns only one element

How can I read the 2 tags with different ID's ? as it only returns once ? ( I don't know the ID's as they are and will be random)

Edited by hippothamus
Link to comment

deleted my post accidently..

In short,

lets read this document:





GetFirstChild seems to return the LAST element, in this case being E, BUT in case E is found multiple times, it returns the FIRST E starting from a

GetPreviousElement returns -24 when the loop reaches the element after A, as it doesn't excist. Couldn't find an explanation for the error code so I assume its ' can't find the previous element'.

The issue it that when E is found multiple times, for example





GetFirstChild starts at position 3. The loop will now find b, a and stop.

Adding another loop in the other direction will find c-d-e (getNextElement) but won't get a -24 after reaching e, instead it starts again at c-d-e-c-d-e-c-d-e and never stops. Too bad, but I assumed comparing the firstchild with each new found element would solve it and break the loop, yes of course..

Sadly, if E is found multiple times, it will stop in between,

on:






First loop: e-b-a

Second loop e-c-e-c-e-c-e-c-e-...

Never loops but would be d-e-d-e-d-e-d-...

There is no way to load the same elements in vw :( ( even if the attributes are different )

Edited by hippothamus
Link to comment
  • 1 month later...

Found a long way around it, not the best but it works.

When using Get/Set-ElementValue you can add brackets to the name of of that element.

If you have 5 times an element "abc" you can load/save the 3th value with "abc[3]". This path can then be used to store/load the attributes and or elements behind/in this tag.

1

2

3

Sadly you have to code the loop which means you can't give the script unlimited options as there is no way to find how many of the same elements are stacked. I needed to use an attribute A-Z, so i'm just checking for the first 26 results.

Findelement can not be used with brackets, thus searching beyond such an element is impossible. It will only give the result for the first element.

The good news: I finaly managed to get my revision list mapped in excell with xml. It looks great.

Edited by hippothamus
Link to comment

Wouter,

???Would something like this work to find out how many Elements there are of each name? Of course, this is totally untested code. Just a thought in passing.

Function CountElements(Hxml :Handle; LMNTName :String) :Integer;

Var

???Done :Boolean;

???I, Rslt :Integer;

???LMNT, Val :String;

Begin

???I := 0;

???Done := False;

???while not Done do begin

??????I := I + 1;

??????LMNT := concat(LMNTName, '[', I, ']');

??????Rslt := GetElementValue(Hxml, LMNT, Val);

??????Done := Val = '';

??????Done := Rslt <> 0;???{ maybe this test would work better }

???end;??????{ while }

???CountElements := I - 1;

End;??????{ CountElements }

HTH,

Raymond

Link to comment

Tested such a loop and it works..

STOP:=FALSE;
i:=0;
WHILE NOT STOP DO BEGIN
{ counter }
i:=i+1;
err := GetAttributeValue(xmlID, concat(elementPath,'[',i,']'),'id',value);
IF err=-3 THEN STOP:=TRUE;

IF (NOT STOP) AND (other stuff) THEN BEGIN
           use this data 
END;
END;

I now never will need to retype any project information in vectorworks, as we now can edit ONE project-database-file both in excel as in vectorworks in 2 directions.

Edited by hippothamus
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...