Re: Help with XML function by Anthony
Anthony
Fri Mar 02 15:32:29 CST 2007
"E C H (He of too much code)" <glasswalkertheurge@juno.com> wrote in message
news:ORNl$lNXHHA.4252@TK2MSFTNGP06.phx.gbl...
>
>
> Anthony Jones wrote:
> > "E C H (He of too much code)" <glasswalkertheurge@juno.com> wrote in
message
> > news:O73Z1cHXHHA.528@TK2MSFTNGP03.phx.gbl...
> > look
> > standards or
> > xmlDoc.documentElement.selectSingleNode(strRootElementPath)
> >
> > Have you tested this code to see what the output would be? Is it really
> > your intention to create multiple 'Sound' elements? OR did you want to
> > create a single 'Sound' element carrying the three attributes?
> Yes, I have tested the code. Upon looking at it again, you are correct,
> organizationally it doesn't make much sense. I just used this for
testing, I
> will be creating the XML file that I showed on a earlier post.
> >
> > Two things that I would consider to be a problem. The function is
coupled
> > to the fact that there is an external variable called xmlDoc upon which
it
> > depends. This isn't good code construction when it can be avoided.
Also
> > the code causes a search for a node "/Options/BasicOptions" three times
> > where one or even none would do.
> Agreed, this is a poor programming! But I have done it because it meets
my
> goals. It is in my opinion much simpler than creating a node with a
separate
> function. It is also easier (in my opinion) to understand.
> >
> > Let's go back to my original function but this time I'll explain what it
is
> > doing:-
> >
> > Function AddElem(roParent, rsName, rvntValue)
> > Set AddElem = roParent.ownerDocument.createElement(rsName)
> > roParent.appendChild AddElem
> > If Not IsNull(rvntValue) AddElem.Text = rvntValue
> > End Function
I've noticed this function is bugged in couple of places. Too much JScript
has lead to there not being a Then in the If. Also whilst a DOMDocument
node has an ownerDocument property it isn't self referencing it's simply
nothing so the function doesn't actually work for the root node.
I didn't notice this because my usual approach would be:-
Dim moDOM : Set oDOM = CreateObject("MSXML2.DOMDocument.3.0")
moDOM.loadXML "<options />"
moBasic = AddElem(moDOM.documentElement,"Basic", Null)
> >
> > The function takes an XMLDOMNode (that can be the DOMDocument itself or
any
> > Element) as the roParent parameter. It uses the parent nodes
ownerDocument
> > property to fetch the DOMDocument the owns the node. This de-couples
the
> > function from having to aware of an external Document variable against
which
> > it needs to call the createElement method.
> Interesting, I will have to look into this. Looks like I will be keeping
my
> code though.
> >
> > It uses the second Name parameter (BTW, the r prefix indicates that the
> > identify is a ByRef parameter of the function) to create the element
that is
> > to be returned as the output of the function.
> That is an interesting idea, my naming scheme is a little different, I
indicate
> stuff like boo (boolean), num (integer), etc.
That's good I do that too but since booleans, longs, objects and strings are
by far the most common types I simply use b, l, o and s. ;)
> >
> > It then appends the created node to the parent node.
> This is my rub, I would like to dynamically create the whole deal with one
> function. In my mind it makes more sense.
> >
> > If the third parameter is not null (I don't use an empty string because
an
> > empty string is a valid value for an element) then the assign it to the
> > text content of the element just created.
> Good call, I am going to switch to NULL. Although I can't think of any
reason
> at the moment to have "", might as well have the option.
If you happen to use this sort of code to generate HTML you will need to do
this to create empty elements where a closing tag is required. Eg. <script
src="theURLHere"></script>
> >
> >
> > Using this function then to do what you want to do above (assuming you
> > actually only want one 'Sound' element) is:-
> >
> > Dim moDOM : Set oDOM = CreateObject("MSXML2.DOMDocument.3.0")
> >
> > Dim moRoot, moBasicOptions
> >
> > Set moRoot = AddElem(moDOM, "Options", Null)
> > Set moBasicOptions = AddElem(moRoot , "BasicOptions", Null)
> >
> > With AddElem(moBasicOptions, "Sound", Null)
> > .setAttributes "On_Error", "True"
> > .setAttributes "On_Success", "False"
> > .setAttributes "On_Complete", "True"
> > End With
> I am going to be creating the structure from the previous XML file as
stated.
> Will make a function to read the values in easier.
> >
> >
> > BTW on a question XML design (which is a little bit subjective to
personal
> > preference). I would replace "BasicOptions" with just "Basic" after all
> > this node is already inside a node called "Options" there is no need to
> > restate that this node represents an option.
> Yes, I need to think more like XML (Option\Basic) makes much sense.
>
> P.S. When I run the TidyXML function it removes "<?xml version="1.0"
> encoding="windows-1252"?>", and I am at a loss. The code is below. Any
ideas?
>
> Sub TidyXML(filXMLnot, filXMLtidy)
> Const ForReading = 1, ForWriting = 2
> Const TristateTrue = -1, TristateFalse = 0, TristateUseDefault = -2
> Const allowOverwrite = True
> Dim asUnicode : asUnicode = TristateTrue ' opens as unicode
> Dim asASCII : asASCII = TristateFalse ' opens as ascii
> Dim asSysDefault : asSysDefault = TristateUseDefault ' opens using system
default
> Dim oFile, oTextStream ' as object(s)
>
> Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
>
> Dim sXML : sXML = filXMLnot
Why are you doing the above line??
> Dim sTidyXML
>
> ' (tidy first step) place each element on a new line
> sTidyXML = Replace(sXML, ">", ">" & vbCrLf)
>
> ' (tidy second step) indent each element
> sTidyXML = Replace(sTidyXML, "<", " <")
>
> ' (third step) remove indent from rootnode tags...
> sTidyXML = Replace(sTidyXML, " <?", "<?")
> sTidyXML = Replace(sTidyXML, vbCrLf & vbCrLf, vbCrLf)
> sTidyXML = Replace(sTidyXML, " <" & sRootNodeName, "<" & sRootNodeName)
> sTidyXML = Replace(sTidyXML, " </" & sRootNodeName, "</" &
sRootNodeName)
>
> ' lastly, change the comment...
> 'sTidyXML = Replace(sTidyXML, "(root comment) xml", "(root comment) TIDY
xml")
>
> sXMLTidySpec = filXMLtidy
Where is sXMLTidySpec defined??
>
> ' write out the tidy file...
> objFSO.CreateTextFile filXMLtidy, allowOverwrite ' creates the file (no
return)...
> Set oXMLOutFile = objFSO.GetFile(filXMLtidy) ' "objectify" the file...
>
> Set oTextStream = oXMLOutFile.OpenAsTextStream(ForWriting) ' ,
TristateUseDefault)
> oTextStream.Write sTidyXML
> oTextStream.Close
>
> Set objFSO = nothing
> End Sub
To be frank. Stop doing that. XML does not need to be created to please
the human eye. There are plenty of (free) tools that will display and even
edit XML contents without out all of the above malarky which will lead to
trouble.
To answer your question I suspect you've passed xmlDoc.XML to the first
parameter, when you do that the encoding in the XML is meaningless since the
XML string is always unicode.