View Full Version : parsing XML
n_withers
2007-10-15, 03:58 PM
I've been doing some research about parsing XML with AutoCAD, and I'm having some difficulty. I think it may be because I'm using ACAD2004, but I could be way off. I'm using the following code:
(setq doc (vla-getinterfaceobject (vlax-get-acad-object) "MSXML.DOMDocument"))
(vlax-invoke-method doc 'Load "C:\\Temp\\myxmlfile.xml")
(setq nodes (vlax-get-property doc 'childNodes))
(setq node (vlax-get-property nodes 'Item 0))
(vlax-dump-object node)
I've tried stepping through the code one line at a time, and find that the second line (vlax-invoke-method...) returns :vlax-false. Nothing works after that. Anybody have any ideas? Before you ask, I did type the directory and filename correctly. I even tried placing the file in the AutoCAD search path, and I tried using the findfile lisp function. It always returns :vlax-false no matter what I do.
I'm not sure if 2004 even supports using the XML DOM. Did AutoDesk not start supporting this functionality untilI a later release? I realize that I could use VBA or I could parse INI files with VLISP. But I'd really like to use VLISP and XML if possible. Thanks.
RobertB
2007-10-15, 05:35 PM
Try MSXML2, not MSXML.
n_withers
2007-10-15, 05:46 PM
I got the same results. I had already tried a few different versions of the MSXML DOM in the first line... all with the same results. I forgot to mention that initially.
RobertB
2007-10-15, 06:02 PM
Have you re-registered the xml library? Here is working code, FWIW.
(defun i:GetWorkspaces (CUIFilename / acad xml nodes i wsList)
(vl-load-com)
(setq acad (vlax-Get-Acad-Object)
xml (vla-GetInterfaceObject acad "MSXML2.DOMDocument"))
(vlax-Invoke xml 'Load CUIFilename)
(setq nodes (vlax-Invoke xml 'getElementsByTagName "WorkspaceConfig")
i (vlax-Get-Property nodes 'Length))
(repeat i
(setq i (1- i)
wsList (cons (vlax-Get-Property (vlax-Get-Property nodes 'Item i) 'Text)
wsList)))
(vlax-Release-Object nodes)
(vlax-Release-Object xml)
wsList)
n_withers
2007-10-15, 06:45 PM
I tried using your codebase below, and that at least got me a different result. Now when I try to access the file I get "0" returned to me instead of ":vlax-false". I assumed that this meant I was successful. But when I try to get any node from the file, it always tells me that the node has no content, children, or length. I'm guessing that 2004 just can't handle this yet. 2004 doesn't use CUI files, so I can't even test your codebase exactly as it is.
Have you re-registered the xml library? Here is working code, FWIW.
(defun i:GetWorkspaces (CUIFilename / acad xml nodes i wsList)
(vl-load-com)
(setq acad (vlax-Get-Acad-Object)
xml (vla-GetInterfaceObject acad "MSXML2.DOMDocument"))
(vlax-Invoke xml 'Load CUIFilename)
(setq nodes (vlax-Invoke xml 'getElementsByTagName "WorkspaceConfig")
i (vlax-Get-Property nodes 'Length))
(repeat i
(setq i (1- i)
wsList (cons (vlax-Get-Property (vlax-Get-Property nodes 'Item i) 'Text)
wsList)))
(vlax-Release-Object nodes)
(vlax-Release-Object xml)
wsList)
RobertB
2007-10-15, 07:13 PM
2004 doesn't use CUI files, so I can't even test your codebase exactly as it is.Here is a sample CUI file for your testing.
FWIW, the return values from the ActiveX interface are generally useless, other than to indicate some form of success.
n_withers
2007-10-15, 08:32 PM
Thanks. After I examined your sample file, I was finally able to trace the problem to an error in my XML file. I had more than one top level element. I figured it out by trying to view my XML file in Internet Explorer.
As a tip to anyone that may be reading this, if you are new to XML, opening/viewing XML files in Internet Explorer is a quick and easy way to find some simple mistakes in your file.
Thanks for the quick responses Robert. You're always on top of things.
RobertB
2007-10-15, 08:37 PM
Happy to help.
n_withers
2007-10-15, 08:38 PM
BTW, what is the significance of the "i:" in the defun statement? I know what "c:" means, but I have never seen "i:".
dgorsman
2007-10-15, 09:21 PM
You can use any character (or sequence of characters) except for c:, as a "scope" item for the function. Similar functions should be grouped together with the same prefix. This makes maintenance far easier, and allows the use of functions with the same name but different processes to be defined separately i.e groupA:Function1 and groupB:Function1.
Rather than using an interface object, I would use (vlax-create-object...) to create a specific XML DOMDocument object for the file (or files) you are connecting to; by creating multiple objects you can simultaneously connect to different XML files. Also recommended is to use MSXML 6.0, as MSXML 3.0 is not fully W3C compliant and doesn't support xsd schemas, 4.0 is a half-ways patch to bring some parts to W3C standards, and 5.0 is only intented for use with MS Office applications. MSXML 6.0 also supports searching via XPATH syntax.
For working with XML files, I use Visual Studio 2005 (Express) - it contains an excellent XML editor including XSD and error support.
vBulletin® v3.6.7, Copyright ©2000-2009, Jelsoft Enterprises Ltd.