AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

xpath v3 - read and write XML documents with XPath syntax
Goto page Previous  1, 2, 3 ... , 19, 20, 21  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
SecurityAnalysis
Guest





PostPosted: Mon Apr 28, 2008 11:29 pm    Post subject: Reply with quote

Thanks Titan! You are giving your script great support!

It's good to know what was wrong. I wasn't able to figure it out. I guess I'll change around a bit in my code to make it all work!
Back to top
SecurityAnalysis
Guest





PostPosted: Wed Apr 30, 2008 12:43 am    Post subject: Reply with quote

Bug? I get "2," instead of "2".

Code:


hand =
(
<HandDetails SiteName="Everest" GameNumber="3105834338" PokerGameType="NLHoldem" BigBlindAmount="2" SmallBlindAmount="1" Ante="0" HandDate="Apr 13,2008 22:08:17" TableName="Suva21" RealMoney="True" IsTourney="False" TourneyBuyin="0" TourneyEntryFee="0" TourneyNumber="" ButtonSeat="3">
<DetailLines>
<DetailLine PlayerName="waz_Q6" Action="Seat" SeatNumber="1" StackSize="375.65"/>
<DetailLine PlayerName="CptFranklin" Action="Seat" SeatNumber="2" StackSize="180.85"/>
<DetailLine PlayerName="ergi" Action="Seat" SeatNumber="3" StackSize="27"/>
<DetailLine PlayerName="yznogood" Action="Seat" SeatNumber="4" StackSize="205.3"/>
<DetailLine PlayerName="220373" Action="Seat" SeatNumber="5" StackSize="190.35"/>
<DetailLine PlayerName="PkrTxsRngr" Action="Seat" SeatNumber="6" StackSize="211.5"/>
<DetailLine PlayerName="yznogood" Action="PostedSB" Amount="1"/>
<DetailLine PlayerName="220373" Action="PostedBB" Amount="2"/>
<DetailLine PlayerName="ergi" Action="HeroCards" Cards="AdTc" />
<DetailLine Action="DealingDownCards" />
<DetailLine PlayerName="PkrTxsRngr" Action="Folds" />
<DetailLine PlayerName="waz_Q6" Action="Folds" />
<DetailLine PlayerName="CptFranklin" Action="Folds" />
<DetailLine PlayerName="ergi" Action="Raises" Amount="27"/>
<DetailLine PlayerName="yznogood" Action="Calls" Amount="26"/>
<DetailLine PlayerName="220373" Action="Folds" />
<DetailLine PlayerName="yznogood" Action="Shows" Cards="AsTh"/>
<DetailLine PlayerName="ergi" Action="Shows" Cards="AdTc"/>
<DetailLine Action="DealingFlop" Cards="Kc8d9h" />
<DetailLine Action="DealingTurn" Cards="Qd" />
<DetailLine Action="DealingRiver" Cards="6s" />
<DetailLine PlayerName="ergi" Action="Wins" Amount="26.6"/>
<DetailLine PlayerName="yznogood" Action="Wins" Amount="26.6"/>
</DetailLines></HandDetails>
)

xpath_load(hand, handvar)
MsgBox, % xpath(hand, "/HandDetails/DetailLines/DetailLine[@PlayerName='CptFranklin']/@SeatNumber/text()")
Back to top
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Wed Apr 30, 2008 8:20 am    Post subject: Reply with quote

There are two DetailLine elements where PlayerName = CptFranklin, so xpath returns two results. The second CptFranklin has no SeatNumber, so the second result is empty.
Back to top
View user's profile Send private message
SecurityAnalysis
Guest





PostPosted: Thu May 01, 2008 10:30 pm    Post subject: Reply with quote

I couldn't get my code to work with 3.13. I got problems like the ones above. Maybe there is a more clever way by me to solve it?

Anyway, the reason I wanted to upgrade to 3.13 is that I saw it had support for strings containing "-" while 3.10 does not. What characters are not supported in strings by 3.13 and what characters are not supported in 3.10?

That would be great to know. Then I could transform those characters before using xpath.
Back to top
Titanz
Guest





PostPosted: Thu May 01, 2008 10:45 pm    Post subject: Reply with quote

Lexicos is correct, you get "2," because there are two nodes that meet the condition before the attribute selector - it's not a bug. To avoid this problem you should always access results with a parsing loop or StringSplit.

Wrong:
Code:
var := xpath(hand, "/HandDetails/DetailLines/DetailLine[@PlayerName='CptFranklin']/@SeatNumber/text()")
MsgBox, %var%


Correct:
Code:
results := xpath(hand, "/HandDetails/DetailLines/DetailLine[@PlayerName='CptFranklin']/@SeatNumber/text()")
StringSplit, var, results, `,
MsgBox, %var1%


Until we have true arrays or better support for overloading I don't see a way around this.
Back to top
SecurityAnalysis
Guest





PostPosted: Fri May 02, 2008 9:24 am    Post subject: Reply with quote

It would be great if you let me know which characters are not supported in strings(cells?) when using XPath 3.10rc3.

XPath 3.10rc3 was able to handle:
Code:

var := xpath(hand, "/HandDetails/DetailLines/DetailLine[@PlayerName='CptFranklin'][@SeatNumber]/@SeatNumber/text()")
MsgBox, %var%


The only reason I saw to update was that it couldn't handle "-" in strings(cells?). But I can transform those characters into other characters before I start using XPath. If you know, it would be great if you can tell me which characters are not supported by XPath 3.10rc3 so I can transform these and then keep using 3.10rc3.
Back to top
Titanz
Guest





PostPosted: Fri May 02, 2008 9:53 am    Post subject: Reply with quote

In theory every version should have supported strings in the format of abcdefghijklmnopqrstuvwxyz0123456789-_: (upper case as well) for element names as the regex was ((?:\w+:)?\w+). I can't remember the version specific bug that meant 3.10 never followed this. What remained consistent throughout v3 was how results were returned - in the form of AutoHotkey type comma delimited pseudo arrays.

This is mentioned briefly in the documentation but perhaps it's my fault for not elaborating clearly enough how the results are supposed to be used. In other programming languages for example, if an array has only one element you still need to call it with myArray[0] rather than just myArray. The same applies here with the use of StringSplit or a parsing loop.

If you have many places in your script which only requires a single value you may find the following helper function useful:

Code:
var := arrayindex(xpath(hand, "/HandDetails/DetailLines/DetailLine[@PlayerName='CptFranklin'][@SeatNumber]/@SeatNumber/text()"))
MsgBox, %var%



arrayindex(r, i = 1, d = ",") {
   r = .%d%%r%%d%
   StringGetPos, p, r, %d%, L%i%
   Return, SubStr(r, p += 2, InStr(r, d, "", p) - p)
}
Back to top
bigsalgo911



Joined: 02 Jul 2008
Posts: 21

PostPosted: Thu Jul 03, 2008 8:32 pm    Post subject: Reply with quote

Sooooo I'm not figuring out how I get output variables using this script for an AHK script. The XML data is accessable via http and there are a few fields I need it to autocopy...but I couldn't figure out by looking at the help for this how to select which fields to copy to output variables.
Can someone help me?
Back to top
View user's profile Send private message
philz



Joined: 05 Jun 2007
Posts: 87
Location: USA

PostPosted: Sat Jul 05, 2008 6:10 am    Post subject: Possible error with this function found Reply with quote

Now my xpath isn't the greatest but I think I may have found an issue with this function. Execute the code and pay attention to the msgboxes to see the error. I believe that by changing an /node/childnode/text() where there are multiple childnode should result in all childnode/text() being changed.

Anyway this xpath function is excellent, regardless. Just thought you might want to know...or I wanted to know that my xpath skills suck.

Code:
xpath(Fruitxml, "/Fruit[+1]/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
xpath(Fruitxml, "/Fruit/Name[+1]")
MsgBox % xpath_save(Fruitxml)
xpath(Fruitxml, "/Fruit/Name/text()","Banana")
MsgBox % xpath_save(Fruitxml)
Back to top
View user's profile Send private message Send e-mail
Guest






PostPosted: Sat Jul 12, 2008 5:19 pm    Post subject: Re: xpath v3 - read and write XML documents with XPath synta Reply with quote

Titan...I have more searching to do, but I wanted to ask is there a way to "walk" or "parse over" an xml file...either with XPath or in any way...pretty much like Loop, Parse or Loop, Parse, CSV but for XML...

Also how complete is XPath 3.12? I don't even know what should work let alone how compatible your implementation is...& the "/rss[+1]/@version" example seems to fail...
Back to top
Titan



Joined: 11 Aug 2004
Posts: 5068
Location: imaginationland

PostPosted: Sat Jul 12, 2008 6:23 pm    Post subject: Re: xpath v3 - read and write XML documents with XPath synta Reply with quote

Quote:
I wanted to ask is there a way to "walk" or "parse over" an xml file
xpath doesn't use DOM so traversal via TreeWalker/NodeIterator is not an option. Instead something like /root/* would select all the child elements of root (irrespective of descendants) and put the result into a CSV which you can loop over in the usual ahk-way.

philz wrote:
I believe that by changing an /node/childnode/text() where there are multiple childnode should result in all childnode/text() being changed.
Quote:
the "/rss[+1]/@version" example seems to fail...
Yes there still are a few bugs with writing new nodes because the current method for parsing relational elements is not so great. However you can get around these quirks using strongly typed paths - e.g.

Code:
; xpath(Fruitxml, "/Fruit/Name/text()","Banana") ; use:

Loop, % xpath(Fruitxml, "Name/count()")
   xpath(Fruitxml, "Name[" . A_Index . "]/text()", "Banana")



These issues should be solved in xpath v4. I can't say when I'll post a release because I'm busy these days, but here's a sneak peek:

Code:
x = <root><node>ext<node atrb="test" void="">nested</node></node></root>

e = node
r = <((?:\w+:)?%e%\b)((?>((?=<)(?!</?\1\b).|[^<]+))|(?R))*</\1>
RegExMatch(x, r, c)

a = atrb
r = <(?:\w+:)?%e%\b[^>]*\b%a%=("|')?((?(1)[^\1]*?(?=\1)|\S*))
RegExMatch(c, r, ca)

MsgBox, //%e%: %c%`n`n//%e%/@%a%: %ca2%

_________________

RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2")
Back to top
View user's profile Send private message Visit poster's website
joebodo



Joined: 28 Apr 2008
Posts: 46

PostPosted: Mon Jul 14, 2008 10:17 pm    Post subject: Reply with quote

How do I clear an the XML variable?

Here's what I'm trying to do (note this is just a stripped down version of my code):

Code:
Loop,...
  convertToXML(listName . A_Index,  xml)
  xpath_save(xml, "test" . A_Index . ".xml)
}

convertToXML(listName, ByRef xml) {
  xml := ""   ; <--------- Would like to initialize/clear the variable here
  xpath(xml, "/" . listName . "[+1]/@version", "2.0")

  loop,Parse,list,`n
  {
    xvalue := "xxx"
    name := "xxx"
    xpath(xml, "/" . listName . "/" . type . "[+1]/" . name . "[+1]/text()", xvalue)
  }
}


On the second iteration, the xml is not produced correctly. It appears that some data is left in the variable from the first iteration. I can get this to work if add another method that creates a new variable - but this is not ideal.

Is there a way to clear the contents of the xml variable?

Thanks
Back to top
View user's profile Send private message
Titan



Joined: 11 Aug 2004
Posts: 5068
Location: imaginationland

PostPosted: Tue Jul 15, 2008 12:04 am    Post subject: Reply with quote

joebodo wrote:
Is there a way to clear the contents of the xml variable?
I don't see a problem with your code, using var := "" should work as the following demonstrates:

Code:
Loop, 3 {
   xml := "" ; uncomment this line to see what happens
   xpath(xml, "/test[+1]/@version/text()", "2.0")
   MsgBox, % xpath_save(xml)
}


Maybe it would help to use VarSetCapacity(xml, 0). Of course if you are running an outdated version of AutoHotkey its worth installing the latest copy if you still get the error.
_________________

RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2")
Back to top
View user's profile Send private message Visit poster's website
joebodo



Joined: 28 Apr 2008
Posts: 46

PostPosted: Tue Jul 15, 2008 1:04 am    Post subject: Reply with quote

Thanks for the reply - I'll give that a try in a minute. In the meantime... is there a (easy) way to insert a block of XML into the current doc?

Here's what I'm looking for:


Code:

;Current Doc
<Redstone 2.0>
  <command>
    <Command>List Add</Command>
    <Callback>list_AddEntry</Callback>
    <name>List Add</name>
  </command>
  <command>
    <Command>List Merge</Command>
    <Callback>list_Merge</Callback>
    <name>List Merge</name>
  </command>
</Redstone>

; Would like to insert the following into the current document
  <command>
    <Command>Volume Unmute</Command>
    <Callback>volume_Command</Callback>
    <name>Volume Unmute</name>
  </command>
Back to top
View user's profile Send private message
Titan



Joined: 11 Aug 2004
Posts: 5068
Location: imaginationland

PostPosted: Tue Jul 15, 2008 1:12 am    Post subject: Reply with quote

joebodo wrote:
is there a (easy) way to insert a block of XML into the current doc?
Yes its fairly straightforward but you need few lines of code:

Code:
xml =
(
<Redstone version="2.0">
  <command>
    <Command>List Add</Command>
    <Callback>list_AddEntry</Callback>
    <name>List Add</name>
  </command>
  <command>
    <Command>List Merge</Command>
    <Callback>list_Merge</Callback>
    <name>List Merge</name>
  </command>
</Redstone>
)

/*
  <command>
    <Command>Volume Unmute</Command>
    <Callback>volume_Command</Callback>
    <name>Volume Unmute</name>
  </command>
*/

xpath_load(xml)

; insert new content > Command:
xpath(xml, "/Redstone/content[+1]/Command[+1]/text()", "Volume Unmute")
; using the last content node insert two new elements:
xpath(xml, "/Redstone/content[last()]/Callback[+1]/text()", "volume_Command")
xpath(xml, "/Redstone/content[last()]/name[+1]/text()", "Volume Unmute")
; if you wanted to insert at the top use content[-1] and [1] instead of [last()] to refer to it

MsgBox, % xpath_save(xml)

_________________

RegExReplace("irc.freenode.net/ahk", "^(?=(.(?=[\0-r\[]*((?<=\.).))))(?:[c-\x73]{2,8}(\S))+((2)|\b[^\2-]){2}\D++$", "$u3$1$3$4$2")
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... , 19, 20, 21  Next
Page 20 of 21

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group