TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Columbia on January 05, 2004, 03:55:54 PM

Title: External Data Storage with XML and VLISP
Post by: Columbia on January 05, 2004, 03:55:54 PM
Alright guys/gals/robots/animals/vermin/rodents,

How many of you store data externally in a database file, a *.ini file, a *.txt file, a flat text *.dat file?

Do any of you know the beauty of XML structured data?  Do any of you care about the beauty of XML structured data?

If you answered yes to any or all of the above questions, then I may have something cool for you to look at and possibly use.  I have been working for a long time on a VLISP API for working with XML documents based on the MSXML DOM (Document Object Model) 3.0.  I am willing to share this thing free of charge to any who would like to use it.  I just want to know if y'all think it might be worth posting somewhere, anywhere.

I would be happy to answer any questions any of you might have about the API or XML in general.  I'm by no means an expert in XML, but I have done a lot of research with the DOM.

Se7en, you might remember me querying some a while back.  It's pretty much done and it's extensive.
Title: External Data Storage with XML and VLISP
Post by: daron on January 05, 2004, 04:52:10 PM
I'd like to see that. I've been reading a book on xml and they covered it a bit at AU.
Title: External Data Storage with XML and VLISP
Post by: Mark on January 05, 2004, 04:55:10 PM
>Do any of you know the beauty of XML structured data?
Yep, use it with Land Desktop, it is very nice. See http://www.landxml.org

How about some ideas of what it could be user for, for the curious.

>I just want to know if y'all think it might be
>worth posting somewhere, anywhere.
I would be willing to give up some server space for the project.
Title: From XML author:
Post by: deegeecees on January 05, 2004, 04:55:28 PM
"Title: XML based Configuration file
Description: This application has a class which handles all the code related to reading frmo and writing into an XML file. This XML file has a common structure.
I developed this so that my applications are not dependent on window's registry or INI files to store configuration information. For example, an application often requires to login into a database. For this it requires either DSN or Driver name, database server name, database name etc. Instead of hard coding this in the application, it is often read from either Window's registry or INI. But XML file is the perfect place to keep this information.
Code also shows how to use it to store configuration file as encrypted.
XML File is very easy to understand. Has only three elements (Configuration, Section and Item). So it is very easy for end-users to modify as well."

This is a DVB file I've downloaded and am looking into rewriting all my VBA stuff to use this method. Very time consuming task.
Title: External Data Storage with XML and VLISP
Post by: JohnK on January 05, 2004, 04:56:19 PM
I'm game. Sounds VERY cool. (I got a new job and I'm not using AutoCAD anymore, but I'm always willing to learn! --Thats why that email addy you had for me then, dosent work anymore.)
Title: External Data Storage with XML and VLISP
Post by: deegeecees on January 05, 2004, 05:30:08 PM
Can I have your old job?
Title: External Data Storage with XML and VLISP
Post by: JohnK on January 05, 2004, 05:31:39 PM
Yeah. Give 'em a call.
Title: External Data Storage with XML and VLISP
Post by: Keith™ on January 05, 2004, 05:45:18 PM
You might rather be unemployed from what I understand.....
Title: External Data Storage with XML and VLISP
Post by: rugaroo on January 05, 2004, 06:25:25 PM
Columbia -

Like Mark had said, I would also be will to allow for some disk space on my server.  Just let me know.

Rug
Title: External Data Storage with XML and VLISP
Post by: JohnK on January 05, 2004, 09:37:31 PM
Columbia,

Does Dave know that you finished this? I seem to remeber him asking about XML and VL, a L..O..N..G time ago. I think he needs a good razzing.
Title: External Data Storage with XML and VLISP
Post by: hendie on January 06, 2004, 03:37:58 AM
Quote from: deegeecees
Can I have your old job?


I think that at the moment, Se7en would be quite prepared to give you his new[/b] job !"  :P
Title: External Data Storage with XML and VLISP
Post by: Columbia on January 06, 2004, 10:23:54 AM
Someone asked for an example type of thingy...  well here goes nothing...

Say you wanted to store a set of standard layer settings outside of an AutoCAD drawing session so that you could use them over and over again.  And let's also say that you wanted to say you want them in a place where you can easliy edit them without having to mess with any source code of any kind.  All that equals an external data file.  Right?  Okay.

Now whether you use an *.ini or some other flat text format, is up to you.  But with XML and the MSXML DOM 3.0 interface it makes programming a little easier.  Mainly because the DOM (Document Object Model) gives the programmer a way to structure data in a logical and nested way (the XML format), as well as giving an Object Oriented way of getting to that data.

Alright here's what an *.ini format might look like for storing layer data...
Code: [Select]

[Layer]
;;; the properties list: color, linetype, lineweight, plottable
Walls=3,continuous,acByLwDefault,True
Furniture=2,PHANTOM,acByLwDefault,True

Now in an XML manner...
Code: [Select]

<Layers>
  <Layer Name="Walls">
    <Color>3</Color>
    <LineType>continuous</LineType>
    <LineWeight>acByLwDefault</LineWeight>
    <Plottable>True</Plottable>
  </Layer>
  <Layer Name="Furniture">
    <Color>2</Color>
    <LineType>PHANTOM</LineType>
    <LineWeight>acByLwDefault</LineWeight>
    <Plottable>True</Plottable>
  </Layer>
</Layers>


Now some might say, "Big deal they do the same thing!"  And they would be essentially right.  But (and there's always a but) using the XML format you can then share that data easily with other types of data storage systems.  A lot of other storage systems, like MS Access, Oracle, and SQL Server, have built in tools for translating XML data into a full service database.  That can't be said about other text formats, like *.ini.

Mark, Rug,
I have a compiled *.vlx for posting as well as a HTM header file that explains the functions within and how to use them.  Where should I send the files?

Se7en,
Yes, Dave does know.  In fact I just showed him the other day the API.  And he had sort of an attitude like, "Great!  Now I don't have to do it."   :D
Title: External Data Storage with XML and VLISP
Post by: JohnK on January 06, 2004, 10:32:40 AM
Quote from: Columbia
{snip} Se7en,
Yes, Dave does know. In fact I just showed him the other day the API. And he had sort of an attitude like, "Great! Now I don't have to do it." :D

HAHA! That sounds like Dave.

BTW, This is really interesting. I cant wait to see what you got on this.
Title: External Data Storage with XML and VLISP
Post by: Mark on January 06, 2004, 10:33:20 AM
Assuming their not to big, e-mail them to me and I will stick them somewhere everyone can see them.

mark.thomas@tampagov.net
Title: External Data Storage with XML and VLISP
Post by: hendie on January 06, 2004, 10:35:40 AM
Quote from: Mark Thomas
...and I will stick them somewhere everyone can see them.


and Cue comment from Dent....
Title: External Data Storage with XML and VLISP
Post by: Mark on January 06, 2004, 10:40:09 AM
>and Cue comment from Dent....
you just _had_ to say something............. :D
Title: External Data Storage with XML and VLISP
Post by: Keith™ on January 06, 2004, 11:19:40 AM
Oh... where is dent... I know he just can't leave this one alone
Title: External Data Storage with XML and VLISP
Post by: deegeecees on January 06, 2004, 02:21:42 PM
I'm not so sure I wanna see em now.... :D
Title: External Data Storage with XML and VLISP
Post by: Mark on January 07, 2004, 11:42:35 AM
The xml-api is available here.

http://www.theswamp.org/swamp.files/xml-api/

Thanks Columbia.
Title: External Data Storage with XML and VLISP
Post by: JohnK on January 07, 2004, 11:53:39 AM
now that is exactly what i was thinking sofar! Awesome!

Ive got so many ideas floating arround in my head now!
Title: External Data Storage with XML and VLISP
Post by: daron on January 07, 2004, 12:02:01 PM
Looks cool. How do we work this stuff?
Title: External Data Storage with XML and VLISP
Post by: Mark on January 07, 2004, 12:15:02 PM
I'm currently working on some more examples. Maybe we could have a thread dedicated Columbia's xml-api , if he doesn't mind that is.
Title: External Data Storage with XML and VLISP
Post by: ELOQUINTET on January 07, 2004, 12:24:13 PM
dent must be out to pasture
Title: External Data Storage with XML and VLISP
Post by: Columbia on January 07, 2004, 12:37:53 PM
Okay,  it looks like we need a little explanation/tutorial/crystal ball to see through all of this stuff.

Let's start out with the contents of a simple XML file that holds AutoCAD Drawing Settings.  The file name of this file will be dwgset.xml
Code: [Select]

<? xml version="1.0"?>     <-- THIS LINE IS CRUCIAL!
<Settings>   <-- Top level parent object  -- only one per XML file.
  <Layers>
    <Layer Name="Walls" Color="2" LineType="continuous"/>
    <Layer Name="Furniture" Color="3" LineType="HIDDEN"/>
  </Layers>
  <DrawingVars>
    <RegenAuto>1</RegenAuto>
    <EdgeMode>0</EdgeMode>
    <Osmode>383</Osmode>
  </DrawingVars>
</Settings>


Now that we have our XML file...  Here are some code samples using the XML-API.vlx

Code: [Select]

(vl-load-com) ;; to make sure everything is peachy with Active-X
(load "xml-api.vlx") ;; load up the API

(setq oSettings (xml-Get-XMLObject "dwgset.xml")) ;; gets the settings element of the xml document object

(setq oLayers (xml-Get-Child oSettings nil "Layers")) ;; gets the Layers collection

(setq oRegen (xml-Get-Child oSettings "DrawingVars" "RegenAuto"))

;; to get the actual value of oRegen you can now use 'Text property as in
(vlax-get-property oRegen 'Text) ;; returns "1"
;; or you can get it this way...
(xml-Get-Child-Value oSettings "DrawingVars" "RegenAuto") ;; returns "1"

;; To  get a Layer object with specific attribute name
(xml-Get-Child-ByAttribute oSettings "Layers" "Name" "Walls")


I hope you guys/gals/robots/etc. get the picture.

Here are a couple of things to be aware of when dealing with XML and VLISP

1. Everything fetched from an XML file is a string.  You will have to post-process the info for type...  It is possible to define what type of data is entered using XML Schema.  But this API does not take that into account.

2. All text IS case sensitive when dealing with an XML file... the function names are not, but the data is.

I hope this can get y'all started.  If you have any specific questions, please ask...

Mark, I don't mind.  I put this out for all to enjoy.  So whatever helps the most...
Title: External Data Storage with XML and VLISP
Post by: SMadsen on January 07, 2004, 02:28:21 PM
Columbia, is this version specific?
If so, which version does it use?

... oh, nevermind - just saw in your first post that it uses 3.0
Title: External Data Storage with XML and VLISP
Post by: Keith™ on January 07, 2004, 03:00:09 PM
You can also import the msxml3.dll type library into Visual Lisp using:
Code: [Select]


(vlax-import-type-library
   :tlb-filename "C:/WINNT/System32/msxml3.dll"
   :methods-prefix "msxm-"
   :properties-prefix "msxp-"
   :constants-prefix "msxc-"
)


The :tlb-filename must point to the location of the file on your system

Then you can have all of the MS XML ActiveX components as well.

To see what they are, in the Visual Lisp editor open the Apropos window and type in the prefixes

msxm-   for methods
msxp-    for properties
msxc-    for constants

The syntax is the same as for the VBA counterparts
Title: External Data Storage with XML and VLISP
Post by: daron on January 07, 2004, 03:15:42 PM
Windows XP pro it is:
Code: [Select]
(vlax-import-type-library
   :tlb-filename "C:/WINDOWS/System32/msxml3.dll"
   :methods-prefix "msxm-"
   :properties-prefix "msxp-"
   :constants-prefix "msxc-"
)


Is there a help file associated with these anywhere?
Title: External Data Storage with XML and VLISP
Post by: Keith™ on January 07, 2004, 03:19:30 PM
Unfortunately there is not a help file installed on the system for the this activex type library. Let me see if I can get anything from MS on this.
Title: External Data Storage with XML and VLISP
Post by: Mark on January 07, 2004, 03:26:09 PM
From MS;
http://tinyurl.com/27xlz
Title: External Data Storage with XML and VLISP
Post by: SMadsen on January 07, 2004, 04:05:40 PM
(vlax-create-object "MSXML.DOMDocument")
or
(vlax-create-object "MSXML2.DOMDocument.3.0")
or
(vlax-create-object "MSXML2.DOMDocument.4.0")

... are equally useful - depending on versions installed of course - if importing a type library is considered overkill.
Title: External Data Storage with XML and VLISP
Post by: JohnK on January 07, 2004, 05:33:35 PM
I need to do some more reading on this subject!

I dont see the purpose of calling any sort of dll when all it really (?) is, is a text file.  ...im i wrong?
Title: External Data Storage with XML and VLISP
Post by: SMadsen on January 07, 2004, 05:51:10 PM
XML is more of a database than text. Nice things can be done with XML and I think MS XML DOM is well worth the effort to get to know.
AutoCAD is making more use of XML for each release. E.g. the toolbar palettes are written in XML and the main exchange format will soon be XML based.
Title: External Data Storage with XML and VLISP
Post by: JohnK on January 07, 2004, 05:55:44 PM
Oh i get cha. Im gonna try to do some reading tonight. Then im gonna work on some flowcharts for some quick tools i could create.
Title: External Data Storage with XML and VLISP
Post by: daron on January 07, 2004, 06:25:21 PM
Also, if I remember correctly, that "swanky" layer dialog that I put up on the ADT forum was written with xml.
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 14, 2008, 10:15:31 AM
It's been 4+ years since I posted the .vlx for the xml-api.  Anybody want the source code?
Title: Re: External Data Storage with XML and VLISP
Post by: daron on May 14, 2008, 10:24:47 AM
Yes, please.
Title: Re: External Data Storage with XML and VLISP
Post by: deegeecees on May 14, 2008, 10:30:46 AM
Yes, please.

Ditto.
Title: Re: External Data Storage with XML and VLISP
Post by: psuchewinner on May 14, 2008, 10:36:02 AM
Columbia.  I just sent you a message.
I am having trouble getting it to work.  Would you, could you, Help me/us?
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 14, 2008, 11:42:40 AM
Okay, you guys asked for it...

Code: [Select]
;;;************************************************************************
;;; api-xml.lsp
;;; Prepared by: J. Szewczak
;;; Date: 4 January 2004
;;; Purpose: To provide an API for interfacing with XML files.
;;; Copyright (c) 2004 - AMSEC LLC - All rights reserved
;;;************************************************************************
;;; Version 2004.01.04
;;;************************************************************************

;;;***********************************************************************
;;; MODULE: api-error
;;; DESCRIPTION: wraps a function to trap Active-X errors - if error is found
;;; DESCRIPTION: function returns nil.
;;; ARGS: function to check, list of arguments, boolean (return error message?) T or nil
;;; EXAMPLE: (api-error '/ (list 50 0) T) displays "VLISP Error: divide by zero" & returns 'nil'
;;;***********************************************************************

(defun api-error (func lst bool / trap)
  (cond
    ( (vl-catch-all-error-p
        (setq trap (vl-catch-all-apply func lst))
      )
      (if bool (princ (strcat "\nVLISP XML Error: " (vl-catch-all-error-message trap))))
      (setq trap nil)
    )
  )
  trap
)


;;;************************************************************************
;;; MODULE: XML-Get-Document
;;; DESCRIPTION: queries an XML file for the DOM Active-X object
;;; ARGS: XML file (string); a variable to store the DOM object
;;; EXAMPLE:(XML-Get-Document projfile 'XMLDoc) returns vla-object
;;;************************************************************************

(defun XML-Get-Document (file XMLDoc)
  (if (findfile file)
    (progn
      (set XMLDoc (vlax-create-object "MSXML2.DOMDocument.3.0")) ;;create XML-DOM pipeline
      (vlax-put-property (eval XMLDoc) "async" :vlax-false)
      (cond
        ( (api-error 'vlax-invoke-method (list (eval XMLDoc) "Load" file) T) ;; Load Project File into XML-DOM pipeline
          (eval XMLDoc)
        )
      )
    )
    (alert "\nXML Document could not be found.")
  )
)

;;;************************************************************************
;;; MODULE: XML-Get-XMLObject
;;; DESCRIPTION: this gets the top-level parent node object in a given XML Document
;;; ARGS: filename (string)
;;; EXAMPLE: (XML-Get-XMLObject filename) returns VLA-OBJECT
;;;************************************************************************

(defun XML-Get-XMLObject (file / docObj xmlTop xmlVer object)
  (if (findfile file)
    (progn
      (setq docObj (XML-Get-Document file 'docObj)
            xmlTop (vlax-get-property docObj "childNodes") ;; Get the Top Level of the XML
            xmlVer (vlax-invoke-method xmlTop "nextNode")  ;; Gets the XML version element
            object (vlax-invoke-method xmlTop "nextNode")  ;; Gets the Parent element
      )
    )
  )
  object
)

;;;************************************************************************
;;; MODULE: XML-Get-ElementKey
;;; DESCRIPTION: returns the requested tags text.
;;; ARGS: Parent - the parent collection object, tag name - must be unique tag name
;;; EXAMPLE: (XML-Get-ElementKey laydef "Name") returns "ANNOTATION"
;;;************************************************************************

(defun XML-Get-ElementKey (parent tag / el desc)
  (if (vlax-method-applicable-p parent 'getElementsByTagName)
    (progn
      (setq el (vlax-invoke-method parent 'getElementsByTagName tag))
      (if (> (vlax-get-property el 'Length) 0)
        (setq desc (vlax-get-property (vlax-invoke-method el 'nextNode) 'text))
      )
      (vlax-invoke-method el 'reset)
    )
    (princ "\nXML Object could not be searched.")
  )
  (if desc desc nil)
)

;;;************************************************************************
;;; MODULE: XML-Get-ElementKey-Object
;;; DESCRIPTION: returns the requested tags object.
;;; ARGS: Parent - the parent collection object, tag name - must be unique tag name
;;; EXAMPLE: (XML-Get-ElementKey-Object laydef "Name") returns VLA-OBJECT
;;;************************************************************************

(defun XML-Get-ElementKey-Object (parent tag / el desc)
  (if (vlax-method-applicable-p parent 'getElementsByTagName)
    (progn
      (setq el (vlax-invoke-method parent 'getElementsByTagName tag))
      (if (> (vlax-get-property el 'Length) 0)
        (setq desc (vlax-invoke-method el 'nextNode))
      )
      (vlax-invoke-method el 'reset)
    )
    (princ "\nXML Object could not be searched.")
  )
  (if desc desc nil)
)

;;;************************************************************************
;;; MODULE: XML-Get-Parent
;;; DESCRIPTION: Gets a top level object from the XML object with the given name
;;; ARGS: a valid XML object, the name of the parent level
;;; EXAMPLE: (XML-Get-Parent oXML "Leaders") returns VLA-OBJECT
;;;************************************************************************

(defun XML-Get-Parent (oXML name)
  (vlax-invoke-method
    (vlax-invoke-method oXML 'GetElementsByTagName name)
   'peekNode
  )
)

;;;************************************************************************
;;; MODULE: XML-Get-Children
;;; DESCRIPTION: gets the child object from a parent level
;;; ARGS: XML object, Parent name
;;; EXAMPLE: none
;;;************************************************************************

(defun XML-Get-Children (oXML parentName / return)
  (cond
    ( (/= parentName nil)
      (if (vlax-invoke-method (XML-Get-Parent oXML parentName) 'hasChildNodes)
        (setq return (vlax-get-property (XML-Get-Parent oXML parentName) 'childNodes))
      )
    )
    ( T (if (vlax-invoke-method oXML 'hasChildNodes) (setq return (vlax-get-property oXML 'childNodes))))
  )
  return
)

;;;************************************************************************
;;; MODULE: XML-Get-ChildList
;;; DESCRIPTION: returns a list of all child objects under a parent XML Object
;;; ARGS: XML object
;;; EXAMPLE: (XML-Get-ChildList objXML) returns a list of VLA-Objects
;;;************************************************************************

(defun XML-Get-ChildList (oXML / collection child lst)
  (cond
    ( (vlax-invoke-method oXML 'hasChildNodes)
      (setq collection (XML-Get-Children oXML nil))
      (while (setq child (vlax-invoke-method collection 'nextNode))
        (setq lst (if lst (cons child lst) (list child)))
      )
      (reverse lst)
    )
    (princ "\nObject has no children")
  )
)

;;;************************************************************************
;;; MODULE: XML-Get-Child
;;; DESCRIPTION: gets a specific child name under the parent level with given name
;;; ARGS: XML object, parent level, child name
;;; EXAMPLE: (setq oPointers (XML-Get-Child oXML "Leaders" "Pointers")) returns VLA-Object
;;; EXAMPLE: (XML-Get-Child oPointers nil "ArrowSize") used you only want to go one deep...
;;;************************************************************************

(defun XML-Get-Child (oXML parentName childName / child target)
  (cond
    ( (/= parentName nil) (setq child (XML-get-Children oXML parentName)))
    ( T (setq child (vlax-get-property oXML 'childNodes)))
  )
  (setq target (api-error 'vlax-invoke-method (list child 'nextNode) T))
  (while
    (and
      target
      (/= (vlax-get-property target 'tagName) childName)
    )
    (setq target (api-error 'vlax-invoke-method (list child 'nextNode) T))
  )
  target
)

;;;************************************************************************
;;; MODULE: XML-Get-Child-ByAttribute
;;; DESCRIPTION: gets a specific child name under the parent level with given attribute and attribute value
;;; ARGS: XML object, parent level, attribute to search by, attribute value to match
;;; EXAMPLE: (XML-Get-Child-ByAttribute oLayers "LayerDefinitions" "Name" "ANNOTATION") returns VLA-OBJECT
;;; EXAMPLE: (XML-Get-Child-ByAttribute oLayerDefs nil "Name" "ANNOTATION") used when you only want to go one deep...
;;;************************************************************************

(defun XML-Get-Child-ByAttribute (oXML parentName attrib attribValue / parent rtn)
  (if parentName
    (setq parent (XML-Get-Child oXML nil parentName))
    (setq parent oXML)
  )
  (foreach itm (XML-Get-ChildList parent)
    (if (= (XML-Get-Attribute itm attrib "") attribValue)
      (setq rtn itm)
    )
  )
  rtn
)

;;;************************************************************************
;;; MODULE: XML-Get-Child-Value
;;; DESCRIPTION: Retrieves the value from the 'Text property of a child element
;;; ARGS: XML object, parent Name, Child Name
;;; EXAMPLE: (XML-Get-Child-Value oXML "TaskInfo" "FSCM") returns "4T323"
;;;************************************************************************

(defun XML-Get-Child-Value (oXML parentName childName)
  (if (XML-Get-Child oXML parentName childName)
    (vlax-get-property (XML-Get-Child oXML parentName childName) 'text)
    nil
  )
)

;;;************************************************************************
;;; MODULE: XML-Put-Child
;;; DESCRIPTION: updates the text in a given child node
;;; ARGS: XML object, parent node name, child node to change, value to change to
;;; EXAMPLE: (XML-Put-Child oXML "DrawingSetup" "DrawingMode" "MicroScale")
;;;************************************************************************

(defun XML-Put-Child (oXML parentName childName valu / child return)
  (if
    (and
      valu
      (setq valu (vl-princ-to-string valu))
      (setq child (XML-Get-Child oXML parentName childName))
    )
    (api-error 'vlax-put-property (list child 'text valu) T)
  )
)

;;;************************************************************************
;;; MODULE: XML-Remove-Child
;;; DESCRIPTION: removes the specified child object node
;;; ARGS: XML node object
;;; EXAMPLE: (XML-Remove-Child oXML)
;;;************************************************************************

(defun XML-Remove-Child (rmvChild / parent)
  (setq parent (vlax-get-property rmvChild 'parentNode))
  (api-error 'vlax-invoke-method (list parent 'removeChild rmvChild) T)
)

;;;************************************************************************
;;; MODULE: XML-Add-Child
;;; DESCRIPTION: adds a Child element to the given parent object
;;; ARGS: Parent Level VLA-Object, name of new child
;;; EXAMPLE: (XML-Add-Child oXML "LayerKey") returns the newly created child node object
;;;************************************************************************

(defun XML-Add-Child (parent name / xmlDoc newElement return)
  (setq xmlDoc (vlax-get-property parent 'ownerDocument))
  (if (not parent) (setq parent xmlDoc))
  (if (setq newElement (api-error 'vlax-invoke-method (list xmlDoc 'createElement name) T))
    (setq return (api-error 'vlax-invoke-method (list parent 'appendChild newElement) T))
  )
  return
)

;;;************************************************************************
;;; MODULE: XML-Get-Attribute
;;; DESCRIPTION: returns an XML object's named attribute value
;;; ARGS: XML object, attribute name (string), a default value to return if there is no value found in the XML object
;;; EXAMPLE: (XML-Get-Attribute oXML "Name" "Default") might return "ANNOTATION"
;;;************************************************************************

(defun XML-Get-Attribute (oXML name default / att return)
  (if (setq att (api-error 'vlax-invoke-method (list oXML 'getAttributeNode name) T))
    (if att
      ;; due to the fact that the Text property strips trailing and leading white characters
      ;; when using the 'get' method.  the Value property has been used instead.
      (vlax-variant-value (vlax-get-Property att "Value"))
      default
    )
  )
)

;;;************************************************************************
;;; MODULE: XML-Get-Attribute-List
;;; DESCRIPTION: returns a list of strings corresponding to the names of the XML object's attributes
;;; ARGS: XML object
;;; EXAMPLE: (XML-Get-Attribute-List oXML) might return ("Name" "Color" "LineType" "LineWeight" "Plottable" "Comment")
;;;************************************************************************

(defun XML-Get-Attribute-List (oXML / lst attCollection count)
  (if (setq attCollection (vlax-get-property oXML 'attributes))
    (progn
      (setq count 0)
      (while (< count (vlax-get-property attCollection 'length))
        (setq lst (append lst (list (vlax-get-property (vlax-get-property attCollection 'item count) 'Name)))
              count (1+ count)
        )
      )
    )
  )
  lst
)

;;;************************************************************************
;;; MODULE: XML-Put-Attribute
;;; DESCRIPTION: function to put an XML attribute value -- will add the attribute if not already there
;;; ARGS: XML object, attribute name (string), a value to change the attribute to
;;; EXAMPLE: (XML-Put-Attribute oXML "Name" "Default") might return vla-object
;;;************************************************************************

(defun XML-Put-Attribute (oXML name valu / att return)
  (cond
    ( valu (setq valu (vl-princ-to-string valu)))
    ( (not valu) (setq valu ""))
  )
  (if (not (XML-Get-Attribute oXML name nil))
    (XML-Add-Attribute oXML name "")
  )
  (api-error 'vlax-invoke-method (list oXML 'setAttribute name valu) T)
)

;;;************************************************************************
;;; MODULE: XML-Add-Attribute
;;; DESCRIPTION: adds an attribute to the Parent Object with given name, and the optional value
;;; ARGS: Parent Level VLA-Object, name of new attribute, value (optional)
;;; EXAMPLE: (XML-Add-Attribute oXML "Name" "Default") returns the newly created attribute XML object.
;;;************************************************************************

(defun XML-Add-Attribute (parent name valu / xmlDoc newAttribute newAtt)
  (setq xmlDoc (vlax-get-property parent 'ownerDocument))
  (if (setq newAttribute (api-error 'vlax-invoke-method (list xmlDoc 'createAttribute name) T))
    (progn
      (setq attNodeMap (vlax-get-property parent 'attributes)
            newAtt (api-error 'vlax-invoke-method (list attNodeMap 'setNamedItem newAttribute) T)
      )
      (if valu (vlax-put-property newAtt 'Text valu))
    )
  )
  newAtt
)

;;;************************************************************************
;;; MODULE: XML-Get-Value
;;; DESCRIPTION: Retrieves the value from the 'Text property of the supplied XML Element object
;;; ARGS: XML object
;;; EXAMPLE: (XML-Get-Value oXML) returns "4T323"
;;;************************************************************************

(defun XML-Get-Value (oXML)
  (api-error 'vlax-get-property (list oXML 'text) T)
)

;;;************************************************************************
;;; MODULE: XML-Put-Value
;;; DESCRIPTION: Puts a text value into the 'Text property of the supplied XML Element object
;;; ARGS: XML object, text string
;;; EXAMPLE: (XML-Put-Value oXML "4T323") returns T if successful nil if not.
;;;************************************************************************

(defun XML-Put-Value (oXML str)
  (api-error 'vlax-put-property (list oXML 'text str) T)
  (if (= (XML-Get-Value oXML) str)
    T
    nil
  )
)

;;;************************************************************************
;;; MODULE: XML-SaveAs
;;; DESCRIPTION: Writes the parsed XML object out to the given file
;;; ARGS: XML document object or XML element object, fully qualified filename to save to
;;; EXAMPLE: (XML-SaveAs oXML "C:\\projects\\npy structure.swp")
;;;************************************************************************

(defun XML-SaveAs (oXML file)
  (cond
    ( (= (vlax-get-property oXML 'nodeTypeString) "element")
      (api-error 'vlax-invoke-method (list (vlax-get-property oXML 'ownerDocument) 'save file) T)
    )
    ( T (api-error 'vlax-invoke-method (list oXML 'save file) T))
  )
)

;;;************************************************************************
;;; MODULE: XML-Save
;;; DESCRIPTION: Writes the parsed XML object out to its parent file
;;; ARGS: XML document object or XML element object
;;; EXAMPLE: (XML-Save oXML)
;;;************************************************************************

(defun XML-Save (oXML / doc file)
  (cond
    ( (= (vlax-get-property oXML 'nodeTypeString) "element")
      (setq doc (vlax-get-property oXML 'ownerDocument))
    )
    ( T (setq doc oXML))
  )
  (setq file (vl-string-subst "\\" "/" (vl-string-left-trim "file:///" (vlax-get-property doc 'url))))
  (api-error 'vlax-invoke-method (list doc 'save file) T)
)

;;;************************************************************************
(princ)

By the way, this uses MSXML2.DOMDocument.3.0 for its library, but that can & should be updated to MSXML2.DOMDocument.6.0.

Happy coding!!!
Title: Re: External Data Storage with XML and VLISP
Post by: daron on May 14, 2008, 12:13:39 PM
Thank you.
Title: Re: External Data Storage with XML and VLISP
Post by: GDF on May 14, 2008, 02:27:05 PM
Okay, you guys asked for it...


By the way, this uses MSXML2.DOMDocument.3.0 for its library, but that can & should be updated to MSXML2.DOMDocument.6.0.

Happy coding!!!


Ok, thanks for sharing it. Now can you give some examples, for us simple minded folks.

Gary
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 15, 2008, 10:51:31 AM
Contents of an example XML File (named C:\dwgset.xml) as follows:

Code: [Select]
<?xml version="1.0"?>
<Settings>
  <Layers>
    <Layer Name="Walls" Color="" LineType="continuous"/>
    <Layer Name="Furniture" Color="3" LineType="HIDDEN"/>
  </Layers>
  <DrawingVars>
    <RegenAuto>1</RegenAuto>
    <EdgeMode>0</EdgeMode>
    <Osmode>383</Osmode>
  </DrawingVars>
</Settings>

Now here are some statements that use the XML-API to query the above XML file.
Code: [Select]
;; Load the VisualLISP stuff
(vl-load-com)

;; Store an Active-X object to the main node ("Settings") of the XML data file.
(setq oSettings (XML-Get-XMLObject "C:\\dwgset.xml"))

;; Store an Active-X object to the "DrawingVars" node of the XML file.
(setq oDwgVars (XML-Get-Child oSettings nil "DrawingVars"))

;; The following two lines return the exact same thing.
;; An string object representing the value stored in the RegenAuto child node of the DrawingVars node.
(setq sRegenValue (XML-Get-Child-Value oDwgVars nil "RegenAuto"))
(setq sRegenValue (XML-Get-Child-Value oSettings "DrawingVars" "RegenAuto"))

;; Return the value that is stored inside a "Color" attribute from the child node of Layers whose "Name" attribute = "Walls"
(setq color
  (read
    (XML-Get-Attribute
      (XML-Get-Child-ByAttribute oSettings "Layers" "Name" "Walls") "Color" "-1")
    )
  )
)

;; if the value for 'color' that we got above is less than the zero (our supplied default argument was -1).
;; then we'll set that attribute to 2.
(if (< color 0)
  (progn
    (XML-Put-Attribute (XML-Get-Child-ByAttribute oSettings "Layers" "Name" "Walls") "Color" 2)

    ;; After changing the Active-X object that is resident in memory,
    ;; we have to save all of our changes back to the XML file.
    (XML-Save oSettings)
  )
)

;; release the objects
(vlax-release-object oSettings)
(vlax-release-object oDwgVars)

And now after the XML-Save function call the XML file should look like this:

Code: [Select]
<?xml version="1.0"?>
<Settings>
  <Layers>
    <Layer Name="Walls" Color="2" LineType="continuous"/>
    <Layer Name="Furniture" Color="3" LineType="HIDDEN"/>
  </Layers>
  <DrawingVars>
    <RegenAuto>1</RegenAuto>
    <EdgeMode>0</EdgeMode>
    <Osmode>383</Osmode>
  </DrawingVars>
</Settings>

I hope that gets y'all on your way...
Title: Re: External Data Storage with XML and VLISP
Post by: psuchewinner on May 15, 2008, 11:53:42 AM
There must be a setting that is wrong with my computer or something that is not loaded because if I copy and paste this, it still does not work.

Do I need to have something load?  The VLX is loaded.

Sorry for not getting this stuff.  I am starting to get frustrated.

This is what I am getting:
(vl-load-com)
_$ (setq oSettings (XML-Get-XMLObject "C:\\dwgset.xml"))
#<VLA-OBJECT IXMLDOMProcessingInstruction 023e8ee8>
_$ (setq oDwgVars (XML-Get-Child oSettings nil "DrawingVars"))
nil
(setq sRegenValue (XML-Get-Child-Value oDwgVars nil "RegenAuto"))
; error: bad argument type: VLA-OBJECT nil
_$ (setq sRegenValue (XML-Get-Child-Value oSettings "DrawingVars" "RegenAuto"))
; error: ActiveX Server returned the error: unknown name: GETELEMENTSBYTAGNAME

Columbia,
As you stated in my other post, I should not get a nil for oDwgVars.....seem like it is crashing there.
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 15, 2008, 01:01:48 PM
Do this in the VLIDE...

Code: [Select]
(setq xmldoc (xml-get-document "c:\\dwgset.xml" 'xmlDoc))
(vlax-dump-object (vlax-get xmldoc 'ParseError))

If there is an error with the file it should show up in the dump listing.
Title: Re: External Data Storage with XML and VLISP
Post by: psuchewinner on May 15, 2008, 01:04:27 PM
#<VLA-OBJECT IXMLDOMDocument2 023ef7a8>
; IXMLDOMParseError: structure for reporting parser errors
; Property values:
;   errorCode (RO) = 0
;   filepos (RO) = 0
;   line (RO) = 0
;   linepos (RO) = 0
;   reason (RO) = ""
;   srcText (RO) = ""
;   url (RO) = ""
T

All is well with the file????
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 15, 2008, 01:06:54 PM
Okay then, copy and paste the source code that I posted earlier in this thread.  Find the line that says "MSXML2.DOMDocument.3.0" and change it to "MSXML2.DOMDocument.6.0".  Load the source code, and the rerun original sample code.
Title: Re: External Data Storage with XML and VLISP
Post by: psuchewinner on May 15, 2008, 01:50:41 PM
when I changed it to "6" I got this error:
 error: bad argument type: VLA-OBJECT nil

When I changed it back to "3", I got a VLA-OBJECT but got nil for the variable "sRegenValue" on the next statement
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 15, 2008, 02:02:45 PM
Try 4 & 5 as well as 3 & 6.  I'm thinking it may be a problem with the MSXML DOM api that you have installed on your PC.
Title: Re: External Data Storage with XML and VLISP
Post by: psuchewinner on May 15, 2008, 03:09:09 PM
No Go there.  I get the same result...the nil...with 3, 4 & 5.  6 doesn't work at all.

Atleast I have found a challenging problem.... :evil:
Title: Re: External Data Storage with XML and VLISP
Post by: psuchewinner on May 19, 2008, 08:33:24 AM
Ok,
I Got it !!!!!!!!! :lol:
Yehaw.
Turns out that the problem was with the XML File.  I used the XML Notepad.
Now on to bigger and better things.

Thanks for the help and sorry for the aggravation.
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 19, 2008, 09:22:39 AM
What was wrong in the XML file?  I want to make sure that the sample I gave everybody else is going to be kosher.
Title: Re: External Data Storage with XML and VLISP
Post by: psuchewinner on May 19, 2008, 04:29:05 PM
I am not sure what was wrong really.  I originally copied it fomr this post and pasted it into a word file and renamed it as an XML file.  When I realized that was not good, I pasted it into the MS XML Notepad and it still did not work right.  This morning I started it from scratch in XML notepad and it worked.   :-D

Nothing like leaning something new.  Guess I will dig into this XML thing next.  I areally appreciate your help and patience.
Title: Re: External Data Storage with XML and VLISP
Post by: lispman21 on May 20, 2008, 01:20:50 PM
I am having a little trouble myself using this API and i am sure it is just because i don't understand what i am doing.  I have an XML file and for testing purposes i want to get the Value of the Object Result_Value in the xml file when the Engine_Code attribute is CC04/BL01 if the Result_field object.

Here is my stab at it but it is not working at all.  I have also attached the xml file.  If you could explain what i am doing wrong it would be greatly appreciated.  I could only attache txt files so you will have to change the file xtension to xml.

Source Code:
Code: [Select]
(vl-load-com)
(load "xml-api.vlx")
(setq oSettings (XML-Get-XMLObject "C:\\RTU-2.xml"))
(setq enginecode
       (read
(XML-Get-Attribute
  (xml-Get-Child-ByAttribute oSettings "Result_Field" "Type" "value")"Engine_Code" "CC04/BL01")
)
      )
(if (= enginecode "CC04/BL01")
  (setq oResultValue (xml-Get-Child-Value oSettings "Result_Value" "Value"))
  )
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 20, 2008, 02:26:25 PM
Okay let's see if we can break this down to a more manageable level...

Code: [Select]
;; Starting the VLIDE runtime module
(vl-load-com)

;; Loads the XML-API.vlx
(load "xml-api.vlx")

;; gets a node object corresponding to the 'Job' level of the XML file.
(setq oSettings (XML-Get-XMLObject ("C:\\RTU-2.xml")))

I'm guessing that after this is where you're running into your wall...
And if I'm guessing correctly then what you want to accomplish is actually what's listed below.

Code: [Select]
;; get down to the Unit node by going through the Product node.
(setq nUnit (XML-Get-Child oSettings "Product" "Unit"))

;; Once we have the Unit node then we can look for the Correct Module, like so...
;; We'll use the Module whose Name is Unit Level for ease of explanation
(setq nModule (XML-Get-Child-ByAttribute nUnit nil "Name" "Unit Level"))

;; Now that that is done, we're going to reach out for the Result Parent Node
(setq nResult (XML-Get-Child nModule "Criteria" "Result"))

;; Okay now we're getting down to the nitty gritty - we're almost there.
;; So now we'll look through the rest of the child nodes, find the one with the correct Result_Field type and
;; then return the Engine_Code value from there.
(setq sVal (XML-Get-Attribute (XML-Get-Child-ByAttribute nResult nil "Type" "value") "Engine_Code" "CC04/BL01"))

;; We set the default value to "CC04/BL01" so at the very least we should get that. 
(if (= sVal "CC04/BL01")
  (progn
    ;; ... keep on coding from here
  )
)

;; And don't forget to release your objects...
(mapcar 'vlax-release-object (list nResult nModule nUnit oSettings))


Hope this Helps!

P.S.
Keep in mind that I didn't debug this or test it.  I just wrote as I went along.  Acutally if there are no bugs, then I would be most surprised.  However, the whole point of the post was to try to lay out how to use the API.  The biggest error I found with the snippet you posted, was that it wasn't going down far enough into the XML nested structure.  - Cheers!
Title: Re: External Data Storage with XML and VLISP
Post by: lispman21 on May 20, 2008, 02:50:34 PM
This helps and explains a whole lot to me.  I also appreciate your quick response and depth of detail in your explanations.  This should come in very handy in the near future for me.
Title: Re: External Data Storage with XML and VLISP
Post by: lispman21 on May 20, 2008, 03:48:37 PM
I know you said you hadn't debugged or tested the code you posted.  I have been looking at it and  below is what i have but the nModule variable returns a value of nil which is messing up the program.  I can't figure out why is it a problem with the xml or the way i have my argument written.  Thanks in advance.

Code: [Select]
;; Starting the VLIDE runtime module
(vl-load-com)

;; Loads the XML-API.vlx
(load "xml Application.lsp")

;; gets a node object corresponding to the 'Job' level of the XML file.
(setq oSettings (XML-Get-XMLObject "C:\\RTU-2.xml"))
;; get down to the Unit node by going through the Product node.
(setq nUnit (XML-Get-Child oSettings "Product" "Unit"))

;; Once we have the Unit node then we can look for the Correct Module, like so...
;; We'll use the Module whose Name is Unit Level for ease of explanation
(setq nModule (XML-Get-Child-ByAttribute nUnit "Unit" "Name" "Unit Level"));; Value returned as nil for some reason

;; Now that that is done, we're going to reach out for the Result Parent Node
(setq nResult (XML-Get-Child nModule "Criteria" "Result"))

;; Okay now we're getting down to the nitty gritty - we're almost there.
;; So now we'll look through the rest of the child nodes, find the one with the correct Result_Field type and
;; then return the Engine_Code value from there.
(setq sVal (XML-Get-Attribute (XML-Get-Child-ByAttribute nResult nil "Type" "value") "Engine_Code" "CC04/BL01"))

;; We set the default value to "CC04/BL01" so at the very least we should get that. 
(if (= sVal "CC04/BL01")
  (progn
   (alert "YEAH") ;; ... keep on coding from here
  )
)

;; And don't forget to release your objects...
(mapcar 'vlax-release-object (list nResult nModule nUnit oSettings))
Title: Re: External Data Storage with XML and VLISP
Post by: Columbia on May 20, 2008, 04:01:08 PM
One thing to be very aware of is that XML file values for attributes and nodes are case sensitive.  And I fell victim to that in my example to you.  I put in to search for "Unit Level" when I should have had "Unit level".  Not much difference to most people, but to the computer it's huge.  Try that out.
Title: Re: External Data Storage with XML and VLISP
Post by: lispman21 on May 21, 2008, 07:49:00 AM
That seemed to be the problem.  Thanks for your help.
Title: Re: External Data Storage with XML and VLISP
Post by: lispman21 on May 22, 2008, 02:36:24 PM
It's me again.  I am starting to understand this a little more and more the longer i fool with it.  I am kind of stuck now though.  I am trying to get to the unit node when the Unit name is one from a list i have constructed in the code below.  The variable nUnit keeps returning nil when it tries to go into the unit node through where agian the unit name is one from a list.  This list of names was constructed by getting the child list under the product node and then using xml-get-attribute to return the name for each child under the product node.  There could be multiple Unit nodes per XML file so i am wanting to make the program run for each unit.  I hope I have made some since of what i am trying to do and what is wrong it just seems hard for me to explain it.  Attached is an xml file with multiple Unit nodes.

Source Code:
Code: [Select]
;;;****************************************************************************************************
;;; XML.lsp                                                                                           *
;;; Prepared by: J. Preston                                                                           *
;;; Date: 21 May 2008                                                                                 *
;;; Purpose: To provide a Program to read an XML file and draw the CAD drawings less their dimensions.*
;;; Copyright (c) 2008 - All rights reserved                                                          *
;;;****************************************************************************************************
;;; Version 2008.05.21                                                                                *
;;;****************************************************************************************************

;;;******************************************************************************
;;; MODULE: C:XML                                                               *
;;; DESCRIPTION: Searches for Unit Module information in user selected XML file *
;;; DESCRIPTION: function returns a CAD Drawing of the needed Air Handling Unit.*
;;;******************************************************************************

(defun C:xml ()
;; Starting the VLIDE runtime module
(vl-load-com)

;; Loads the XML-API.vlx
(load "xml Application.lsp")
;;(load "CV AHU.LSP")

;; gets a node object corresponding to the 'Job' level of the XML file.
(setq oSettings (XML-Get-XMLObject (getfiled "Get XML File" "C:\\" "XML" 2)))
;; get down to the Product node.
(setq UName (XML-Get-Child oSettings nil "Product"))

;; get down to the Unit node by going through the Product node.
(setq nUnito (XML-Get-Child oSettings "Product" "Unit"))
 
;; Getting the list of Child nodes to use for a counting mechanism in my while statement
(setq childlist (XML-Get-Childlist nunito))
 
;;;; Getting the number of units in XML and Unit Names
;;Getting VLA-OBJECT List of names of the children under the product node 
(setq childlist2 (XML-Get-Childlist UName))
;; getting the number of children
(setq num1(Length childlist2))
;; setting counter for unit names
(setq UCount 0)
(setq UList '())
;; Process the list of children and return their Names in a list
(While (< UCount num1)
  ;; Getting the name of the first VLA-OBJECT in the child list
  (setq UNAME2 (xml-get-attribute (car childlist2) "Name" nil))
   ;; making a list of the names
   (setq UList (if UList (append UList (list UNAME2))(list UNAME2)))
   ;; removing the VLA-OBJECT that was just used
   (setq childlist2(cdr childlist2))
  ;; Increasing the counter by one
  (setq UCount (+ UCount 1))
);; End of While Statement
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq MCount 0);; initializing counter for main program
(While (< MCount num1)
 
 ;;Now were specifying our selection to be the Unit with the Name from the child list
(setq nunitname (XML-Get-Child-ByAttribute UName nil "Name" (car UList)))
 
 ;;get down to the Unit node where the unit name is the one from the list
(setq nUnit (XML-Get-Child nunitname nil "Unit"))
 
;; Now were specifying our selection to be the Module with the Name Unit Level
(setq nunitlevel (XML-Get-Child-ByAttribute nUnit nil "Name" "Unit level"))
 
;; Now we're stepping down into the node "Result"
(setq nUnit1 (XML-Get-Child nunitlevel "Criteria" "Result"))
 
;; Specifying our search for the result_value we want in this case the FCAT which is UBAS
(setq ULBase (XML-Get-Child-ByAttribute nUnit1 nil "FCAT" "UBAS"))
 
;; Stepping down into the nod Result_Value
(setq ULBase2 (XML-Get-Child ULBase nil "Result_Value"))
 
;;Getting the Value of FCODE from the Result_Value node under FCAT UBAS
(setq ULBase3 (xml-get-attribute ULBase2 "FCODE" nil))
 
;; Detailing what the "Base Height" value should be depending on the value returned.
(if (= ULBase3 "BR06")
  (setq BHT 6.0)
(if (= ULBase3 "BR08")
  (setq BHT 8.0)
(if (= ULBase3 "BR10")
  (setq BHT 10.0)
)))
;; getting the amount of items in the list and subtracting 2 for unit level and controls package
(setq num (-(length childlist)1))
  (setq count 1);; initializing counter
      (setq len 0);; resetting the values
      (setq len2 '());; resetting the List

;; Starting while statement to retrieve Unit Size information.  The counter is set so that length values for the modules
;; will be returned.  If i need to see the values returned i compiled them into a list under the variable len2
  (While (< count num)
    (setq count1 (rtos Count 2 0));; setting the counter interger to a string

;; Once we have the Unit node then we can look for the Correct Module, like so...
;; We'll use the Module whose Module_Number is 1 (using a counter for the actual number) for ease of explanation
     (setq nModule (XML-Get-Child-ByAttribute nUnito nil "Module_Number" Count1))
;; getting the Length value of the Current module   
      (setq sval4 (xml-get-attribute nModule "Length" nil))
;; converting the value of Length into a real number   
       (setq svalatof (atof sval4))
;; Adding all the length of the modules together
        (setq len (if len (+ len svalatof)(+ svalatof 0)))
;; Compiling a list of all the lengths that were returned for each module number
        (setq len2 (if len2 (cons len2 svalatof)(list svalatof)))
;; stepping the counter up by 1
    (setq count (+ count 1))
 );; end of while
 
;; Now that that is done, we're going to reach out for the Result Parent Node
;(setq nResult (XML-Get-Child nModule "Criteria" "Result"))
  (setq HT (Atof(xml-get-attribute nModule "Height" nil)));; getting the Height value of the Unit
  (setq wdth (Atof(xml-get-attribute nModule "Width" nil)));; getting the Width value of the Unit
  ;;(c:CV2 HT len wdth BHT);; calling the program that draws the unit skeleton and passing 4 variables to it

  (setq Ulist (cdr Ulist))
  (setq MCount (+ MCount 1))
 );; end of Big While
 
;; Okay now we're getting down to the nitty gritty - we're almost there.
;; So now we'll look through the rest of the child nodes, find the one with the correct Result_Field type and
;; then return the Engine_Code value from there.
;(setq sVal  (XML-Get-Child-ByAttribute nResult nil "FCAT" "OPG2"))
;(setq nResult2 (XML-Get-Child sval nil "Feature"));; stepping down to the Feature node when Result_Field node attribute FCAT has a value of OPG2
;(setq sval2 (xml-get-attribute nResult2 "SizeY" nil));; Getting the value of the attribute "SizeY" in the Feature node
;(setq svalatof (atoi sval4));; converting the value of SizeY into a real number
;;;   (setq mypnt (getpoint))
;;;   (setq line1 (polar mypnt (dtr 0)len))
;;;   (command "line" mypnt line1 "")
;; We set the default value to "CC04/BL01" so at the very least we should get that. 
;;;(if (/= sVal4 "")
;;;  (progn
;;;   ;; ... keep on coding from here
;;;   (setq line1 (polar mypnt (dtr 0)svalatof))
;;;   (command "line" mypnt line1 "")
;;;  )
;;;)

;; And don't forget to release your objects...
(mapcar 'vlax-release-object (list nModule nUnit nUnito oSettings nUnitlevel nUnit1 ULBase ULBase2 UName nUnitname))
)
Title: Re: External Data Storage with XML and VLISP
Post by: lispman21 on May 23, 2008, 08:28:42 AM
Ok, I beleive i figured out my problem i posted previous to this post.  I was already in the unit node so therefore i couldn't find it when i was trying to call it.
Title: Re: External Data Storage with XML and VLISP
Post by: MiD-AwE on December 31, 2013, 02:12:38 PM
I am one of those folk that believes in reviving old threads instead of starting anew. I hope no one rips me a new one for my belief  :ugly: (BTW-this is my first post.)

I'm trying to use the XML-API.lsp but I'm struggling with one thing. I need a way to create the xml file as I need it, instead having to build a massive xml file with all possible options before hand.

Am I the only one thinking this way and if so is it a bad idea? Will the xml-api flop if the file is not pre-existing?

I would like a function that I can use inline like (XML-Set-Child PARENTNAME NEWCHILDNAME VALUE) & similar for new parent and so on.

Thank you in advance.
Title: Re: External Data Storage with XML and VLISP
Post by: Mark on December 31, 2013, 02:34:51 PM
I am one of those folk that believes in reviving old threads instead of starting anew.
You picked a good one too. :) I had forgotten all about this thread.
Title: Re: External Data Storage with XML and VLISP
Post by: CAB on December 31, 2013, 03:10:38 PM
Welcome to the Swamp MiD-AwE (http://www.theswamp.org/index.php?action=profile;u=15418)
Make sure you check out the XML threads http://goo.gl/53wuPW
Title: Re: External Data Storage with XML and VLISP
Post by: MiD-AwE on January 02, 2014, 10:02:52 AM
Welcome to the Swamp MiD-AwE (http://www.theswamp.org/index.php?action=profile;u=15418)
Make sure you check out the XML threads http://goo.gl/53wuPW

Thank you for the greetings. I'll read through the results, hopefully I'll find something useful.  :|
Title: Re: External Data Storage with XML and VLISP
Post by: eddybeerke on March 29, 2024, 08:26:22 AM
I need to read a XML file and ren in to this post.
I didnt get the api-xml to work properly, so i made this:

XML-File (ofc the original file is a lot bigger, like 2.339 kB  :idiot2:)
Code: [Select]
<?xml version="1.0" encoding="ISO-8859-1"?>
<objects>
<Object nummer="1" hoofdgroep="2" omschrijving="AANKLEDING" />

lisp-file
Code: [Select]
(defun c:foo ( / oXML childNodes item attribute attribute_name nummer)
  ;; Load the VisualLISP stuff
  (vl-load-com)
 
  (setq oXML (XML-get-XMLObject "C:/TEST_READ_XML/objects.xml"))
  ; lees de childNodes
  (setq childNodes (vlax-get-property oXML "childNodes")) 
  (vlax-for item childNodes
    ;(vlax-dump-object item)
    ; lees attributes
    (vlax-for attribute (vlax-get-property item 'attributes)
      (cond
        ((= (setq attribute_name (vlax-get-property attribute 'basename)) "nummer")       (setq nummer         (vlax-get-property attribute 'text)))
        ((= (setq attribute_name (vlax-get-property attribute 'basename)) "omschrijving") (setq omschrijving   (vlax-get-property attribute 'text)))
      )
    )
    (princ (strcat"\n" nummer " | " omschrijving "\n"))
  )
  ;; release the objects
  (vlax-release-object oXML)
 
  (princ)
)

Hoping to help someone.
Title: Re: External Data Storage with XML and VLISP
Post by: Lee Mac on March 29, 2024, 12:56:40 PM
You might find this thread useful:
https://www.theswamp.org/index.php?topic=33065.0