find and replace lines in xml file

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
AndreySibiryakov
Posts: 33
Joined: 09 Jan 2015, 13:19

find and replace lines in xml file

02 Nov 2015, 05:49

Hello.

I have this 3 lines to search for and replace with a similar lines where only some parameters changed.

Code: Select all

            <link function="square_root" from="H" to="lc_u">
                <parameters num_params="1">1.000000 </parameters>
            </link>
I've tried to make a variable of "search for" and "replace with" but got no result.
Then I figured out this command, trying at least, to delete these lines

Code: Select all

RegExReplace(text, "<link function.*(" rFromLine ").*</link>", "")
but, that didn't work.
I've tried "stringReplace" also, with no success.

Please, help me to solve this task.
MJs
Posts: 454
Joined: 23 Sep 2014, 03:29

Re: find and replace lines in xml file

02 Nov 2015, 06:24

can't you use xml dom and select the nodes you want to delete or replace.
that aside, what's in that rFromLine?
you may need to use one of the regex options. you can find the options in the docs "RegEx: Quick Reference"
User avatar
JoeWinograd
Posts: 2214
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: find and replace lines in xml file

02 Nov 2015, 09:55

Hi MJs,

> use xml dom

Can you provide some links that explain using "xml dom"? I did a search for it here but got this:
The following words in your search query were ignored because they are too common words: xml dom.
You must specify at least one word to search for. Each word must consist of at least 4 characters and must not contain more than 84 characters excluding wildcards.
Thanks, Joe
xml

Re: find and replace lines in xml file

02 Nov 2015, 10:07

Try search for MSXML2.DOMDocument.6.0 + autohotkey for various examples. Very simple example below just reading, MsgBox will show 1.000000 and 2.000000

Code: Select all

data=
(join`r`n
<ProjectData>
	<link function="square_root" from="H" to="lc_u">
                <parameters num_params="1">1.000000 </parameters>
  </link>
	<link function="square_root" from="H" to="lc_u">
                <parameters num_params="1">2.000000 </parameters>
  </link>
</ProjectData>  
)

o := ComObjCreate("MSXML2.DOMDocument.6.0")
o.async := false
o.loadXML(data)

functions := o.selectNodes("/ProjectData/link") ;Loop

for node in functions
	msgbox % node.text
MJs
Posts: 454
Joined: 23 Sep 2014, 03:29

Re: find and replace lines in xml file

02 Nov 2015, 11:17

xml provided a simple nice example.
if you can explain what you want to do, another example can be more helpfull
and a search in the forum here, or any tutorial about msxml would help you understand more.
User avatar
JoeWinograd
Posts: 2214
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: find and replace lines in xml file

02 Nov 2015, 11:30

> Very simple example below

Works perfectly! I don't want to hijack Andrey's thread, but this is very valuable to me, so I hope you (and Andrey) won't mind one more question on it. Suppose this is the XML:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<OrderInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <OrderedBy>
    <UserType>1234</UserType>
    <UserID>56789</UserID>
  </OrderedBy>
</OrderInfo>
How would I use "MSXML2.DOMDocument.6.0" to create AHK variables containing the contents of UserType (i.e., 1234) and UserID (i.e., 56789)? Thanks much, Joe
User avatar
JoeWinograd
Posts: 2214
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: find and replace lines in xml file

02 Nov 2015, 11:44

Hi MJs,

> a search in the forum here

Our messages crossed - I replied to xml before seeing your post. I'm working on a script to parse XML. I did a lot of searching for XML parsers here, studied numerous threads, which I either didn't understand or couldn't get the code in them to work, so I wound up writing my own XML parser. But it's not as robust as I would like, so if there's an existing robust parser that I can get working, that would be great.

> explain what you want to do

My vision is to call a function with an input parameter that is the fully qualified XML element and have the function return its value. Something like this:

Code: Select all

XMLelement:="OrderInfo/OrderedBy/UserID"
UserID:=GetValueXML(XMLelement)
Regards, Joe
xml

Re: find and replace lines in xml file

02 Nov 2015, 14:15

This should get you going:

Code: Select all

data=
(join`r`n
<?xml version="1.0" encoding="utf-8"?>
<OrderInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<OrderedBy>
<UserType>1234</UserType>
<UserID>56789</UserID>
</OrderedBy>
</OrderInfo>
)

o := ComObjCreate("MSXML2.DOMDocument.6.0")
o.async := false
o.loadXML(data)
 
node:=o.selectSingleNode("//OrderInfo/OrderedBy/UserType")
UserType:=Node.text
node:=o.selectSingleNode("//OrderInfo/OrderedBy/UserID")
UserID:=Node.text
MsgBox % UserType ":" UserID

;- note the difference here, grab both at the same time

node2:=o.selectSingleNode("//OrderInfo/OrderedBy")
MsgBox % node2.text
User avatar
JoeWinograd
Posts: 2214
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: find and replace lines in xml file

02 Nov 2015, 14:36

> This should get you going

Yes it does! Fantastic! Is there some doc where I can learn about the calls you made (o.selectNodes and o.selectSingleNode) and to see if there are any others? Thanks again, Joe
User avatar
JoeWinograd
Posts: 2214
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: find and replace lines in xml file

02 Nov 2015, 16:11

Thanks, xml, I'll study that link thoroughly (and the MSDN links that it shows), but a quick question first: What is the purpose of the double slash (//) at the beginning? I can understand the single slash (/) as a separator between the parents and children in nested tags, but it seems to me that a double slash, or even a single one, is not necessary at the beginning, as the first item in such a string is, by its very placement, the parent tag of everything that follows. Thanks again, Joe
MJs
Posts: 454
Joined: 23 Sep 2014, 03:29

Re: find and replace lines in xml file

03 Nov 2015, 06:44

it's all about what's called the context node [where you are in the document]
that's where to start the search for the node in the xpath from.
I can understand your point, but that only true beacause the search starts from the root of the document since it's the selected node, so if the selected node isn't the root of the document you have to use or not use the slashes.
//: Recursive descent; searches for the specified element at any depth. When this path operator appears at the start of the pattern, it indicates recursive descent from the root node.
here is an example yo show that you :

Code: Select all

data=
(join`r`n
<?xml version="1.0" encoding="utf-8"?>
<OrderInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<OrderedBy>
<UserType>1234</UserType>
<UserID>56789</UserID>
</OrderedBy>

<OrderedBy><OrderedBy>
<UserType>abcd</UserType>
<UserID>abcd</UserID>
</OrderedBy></OrderedBy>

</OrderInfo>
)
 
o := ComObjCreate("MSXML2.DOMDocument.6.0")
o.async := false
o.loadXML(data)
 
node:=o.selectSingleNode("//OrderInfo/OrderedBy/UserType")
UserType:=Node.text
MsgBox % UserType
 
 
 
 
; let's select NOT root node
selectednode := o.selectSingleNode("//OrderInfo/OrderedBy/OrderedBy")

node1 := selectednode.selectSingleNode("UserType")
node2 := selectednode.selectSingleNode("/UserType")
node3 := selectednode.selectSingleNode("//UserType")
node1text:=node1.text
node2text:=node2.text
node3text:=node3.text

MsgBox,, xml, No slashes:"%node1text%"`nOne slashe:"%node2text%"`ntwo slashes:"%node3text%"

but it seems to me that a double slash, or even a single one, is not necessary at the beginning
that's why it is necessary.
by its very placement, the parent tag of everything that follows
by its very placement in what context, for you it's the top node, but you could be operating on any node, a node at the end of the document, there for the very placement of the xpath and the parent tag is the last node [the context node].
User avatar
JoeWinograd
Posts: 2214
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: find and replace lines in xml file

03 Nov 2015, 12:08

Thank you, MJs - very helpful! Raises a question that I hadn't thought of before. In the selectSingleNode syntax, how do you distinguish between a tag at the same level and a tag that is a child if they have the same name? Example:

Code: Select all

1  <OrderInfo>
2    <OrderedBy>
3      <OrderedBy>
4      </OrderedBy>
5    </OrderedBy>
6    <OrderedBy>
7    </OrderedBy>
9  </OrderInfo>
Does "//OrderInfo/OrderedBy/OrderedBy" refer to line 3 or 6? Whichever one it refers to, what is the syntax to refer to the other one? Thanks, Joe
MJs
Posts: 454
Joined: 23 Sep 2014, 03:29

Re: find and replace lines in xml file

03 Nov 2015, 15:30

think of the word "Context Node".
you need to read a little bit more about the xpath and context node
that xpath "//OrderInfo/OrderedBy/OrderedBy" has no meaning on its own, it takes its meaning from the context node
here is an example with the use of GetAttribute, SelectSingleNode and SelectNodes

Code: Select all

  data=
(join`r`n
  <OrderInfo>
	<OrderedBy n="3"></OrderedBy>
    <OrderedBy n="6"></OrderedBy>
  </OrderInfo>
  
)
 
xmldoc := ComObjCreate("MSXML2.DOMDocument.6.0")
xmldoc.async := false
xmldoc.loadXML(data)

xpath = //OrderInfo/OrderedBy[1] ; the xpath for the first OrderedBy
node:=xmldoc.selectSingleNode(xpath)
t:=Node.getattribute("n")
msgbox % "first node - " t

xpath = //OrderedBy[2] ; ; the xpath for the first OrderedBy, you can lose the //OrderInfo, since you looking for nodes in the root document
node:=xmldoc.selectSingleNode(xpath)
t:=Node.getattribute("n")
msgbox % "second node - " t

xpath=//OrderInfo/OrderedBy

nodes:=xmldoc.selectnodes(xpath) ; selectnodes returns a collection of nodes
for node in nodes
{
	t := Node.getattribute("n")
	msgbox % "node " A_Index " :" t

}
User avatar
JoeWinograd
Posts: 2214
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: find and replace lines in xml file

03 Nov 2015, 16:31

Thanks, MJs - very helpful again! I'll read up on xpath and context node. I'm feeling guiltier by the question for hijacking Andrey's thread, but, as is often the case, one answer leads to another question. This has happened again, but this time I posted it in a new question:

http://ahkscript.org/boards/viewtopic.php?f=5&t=10116

If you and xml and whoever else is interested could look at the new question, I'd appreciate it. Regards, Joe

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: peter_ahk and 356 guests