mIRC Home    About    Download    Register    News    Help

Print Thread
#219699 25/03/10 11:18 PM
Joined: Jun 2009
Posts: 9
B
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
B
Joined: Jun 2009
Posts: 9
I'm trying to get info from a XML database named items.xml. There are several thousand entries and I want to be able to use
!item <item name>

For example:
!item Lustrous Thrall's Ruined Gloves
!item Basalt Sword of Anarchy

The XML is setup like this:
Code:
	<item>
		<armor af="66">SCALE</armor>
		<uid>1</uid>
		<name>Lustrous Thrall's Ruined Gloves</name>
		<origin>Dropped/sold by 'ursine thrall' in 'Treibh Caillte' at locs 26k, 19k</origin>
		<position>GLOVES</position>
		<lastupdate>07.01.2007 18:14:49</lastupdate>
		<realm>Hibernia</realm>
		<level>34</level>
		<quality>90</quality>
		<bonus>20</bonus>
		<description>Item on Uthgard</description>
		<effect id="QUICKNESS">15</effect>
		<effect id="RES_CRUSH">5</effect>
		<effect id="HITPOINTS">20</effect>
	</item>
	<item>
		<weapon dps="16,5" speed="4,2">SLASH</weapon>
		<uid>3</uid>
		<name>Basalt Sword of Anarchy</name>
		<origin>Dropped/sold by 'Legion' in 'Darkness Falls' at locs 36k, 43k</origin>
		<position>WEAPONS</position>
		<lastupdate>07.01.2007 18:14:49</lastupdate>
		<realm>Albion</realm>
		<level>50</level>
		<quality>100</quality>
		<bonus>35</bonus>
		<description>Item on Uthgard</description>
		<effect id="SLASH">2</effect>
		<effect id="STRENGTH">15</effect>
		<effect id="QUICKNESS">15</effect>
		<effect id="RES_MATTER">7</effect>
	</item>


And I'm trying to get the results as:
Lustrous Thrall's Ruined Gloves (Scale) - Lvl: 50, Qual: 90, AF: 66 - Quickness: 15, Crush Resist: 5, Hits: 20 - Dropped/sold by 'ursine thrall' in 'Treibh Caillte' at locs 26k, 19k


Basalt Sword of Anarchy (Slash) - Lvl: 50, Qual: 100, DPS: 16.5, Spd: 4.2 - Slash: 2, Strength: 15, Quickness: 15, Matter Resist: +7 - Dropped/sold by 'Legion' in 'Darkness Falls' at locs 36k, 43k

Not sure if this is possible, or if anyone wants to help out, but just thought I'd ask... thanks in advance!

Or if anyone knows how to bring it up on php I can just use sockets... once again, thanks!

Last edited by Borg8401; 26/03/10 12:46 AM.
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
It shouldn't be too hard. Just use $read() to find the item, then calculate $readn - 2 (this gets you to line 1 in the item list for the selected item). Then, just increment the read line until you've set variables for everything in the item and display via msg.

If no one else wants to help out, I might be able to later on. It really isn't a difficult script. You could probably do it yourself if you know anything about scripting.

/help on text
/help $read
/help $readn
/help $calc
/help if then else
/help /msg
/help /var
/help /inc

That pretty much covers everything you might need to complete the script.


Invision Support
#Invision on irc.irchighway.net
Joined: Jun 2009
Posts: 9
B
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
B
Joined: Jun 2009
Posts: 9
Alright, tried giving it a shot, any suggestions? This didn't work.

Code:
on *:text:*!item*:#: {
  $read(items.xml, *name> $+ $2- $+ <*)
  %type = $read(items.xml, $calc($readn - 2))
 msg $chan %type
}

Last edited by Borg8401; 27/03/10 09:27 PM.
Joined: Feb 2009
Posts: 133
C
Vogon poet
Offline
Vogon poet
C
Joined: Feb 2009
Posts: 133
i'll give u something just for help

Code:
alias t return $regsubex($read(file.txt,w,$+(*,<,$1,>,*)),<.+>(.+)<.+>,\1)

use
$t(name)
$t(position)
$t(...)


WorldDMT
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
The following is very specific to the given data sample. Means, you may have to fine-tune it on your own - good luck wink
Code:
on *:text:*!item *:#: {
  ; your file
  var %file = items.xml
  ; read for <name> line
  var %search = $+($chr(9),$chr(9),<name>,$$2-,</name>)
  noop $read(%file,nts,%search)
  ; <name> line found
  if ($readn) {
    var %a = $v1
    ; search following </item> line
    noop $read(%file,nts,$+($chr(9),</item>),%a)
    if ($readn) && ($v1 != %a) {
      var %b = $v1
      ; filter all the lines of this <item> to an alias (to parse the xml tags >> set variables for output)
      filter -frk $+($calc(%a -2),-,$calc(%b -1)) $qt(%file) xml.filter
      xml.output
    }
    else { ECHO -sg Error: cannot find end tag for item }
  }
  else { msg $chan No such item found. Use exact item name, no quotes. }
}

; convert xml data into variables (I added -s switches to the SET commands for you to see what it does / does not set) 
alias -l xml.filter {
  if ($regex($1-,/^\t{2}<(\S+)(.*)>([^<]+)</)) {
    if ($regml(1) == effect) { SET -s %xml.effects $addtok(%xml.effects,$xml.case($noqt($gettok($regml(2),2,61))) $+ : $regml(3),1) }
    else {
      SET -s %xml. $+ $regml(1) $regml(3)
      if ($regml(2)) {
        var %n = 1
        while ($gettok($regml(2),%n,32)) {
          SET -s %xml. $+ $gettok($v1,1,61) $xml.replace($noqt($gettok($v1,2-,61)))
          inc %n
        }
      }
    }
  }
}

; set "Case"
alias -l xml.case { return $upper($left($1-,1)) $+ $lower($mid($1-,2)) }

; replace commas with dots (for digits), list of other replace strings (extend this as required)
alias -l xml.replace { return $replacex($1-,$chr(44),$chr(46),Res_crush,Crush Resist,Res_matter,Matter Resist) }

; output formatting, output, cleanup
alias -l xml.output {
  ; Item name / Item type / Item level / Item quality
  var %type = $xml.case(%xml.weapon $+ %xml.armor)
  var %out1 = %xml.name ( $+ %type $+ ) - Lvl: %xml.level $+ $chr(44) Qual: %xml.quality $+ $chr(44)
  ; AF / DPS / Speed
  var %out2 = $iif(%xml.af,AF: $v1 $+ $chr(44)) $iif(%xml.dps,DPS: $v1 $+ $chr(44)) $iif(%xml.speed,Spd: $v1 $+ $chr(44))
  ; Effects / Origin
  var %out3 = $replace($xml.replace(%xml.effects),$chr(1),$+($chr(44),$chr(32))) - %xml.origin

  ; output
  msg $chan %out1 %out2 %out3
  unset %xml.*
}


Edit: some typos

Last edited by Horstl; 27/03/10 11:57 PM.
Joined: Feb 2009
Posts: 133
C
Vogon poet
Offline
Vogon poet
C
Joined: Feb 2009
Posts: 133
i have another method but I am based on XML he has presented

Code:
on *:text:*:#:{
  if ($strip($1) == !item) && ($2) {
    var %i 1
    while $read(fichier.txt,%i) {
      if $regsubex($v1,.+>(.+)<.+,\1) == $2- {
        wr $readn # $v1
        halt
      }
      inc %i
    }
  }
}
alias -l wr {
  var %x $1,%chan $2,%c $3-
  while $read(fichier.txt,%x) {
    var %ex $v1
    if !$regex(%ex,</item>) {
      noop $regex(%ex,<(.+)>(.+)<)
      if ($gettok($regml(1),2,34)) var % $+ $v1 $regml(2)
      elseif ($regml(1)) var % $+ $v1 $regml(2)
    }
    else goto r
    inc %x
  }
  :r
  noop $regex($read(fichier.txt,$(},$(},$1))),\s(.+)<.+>)
  tokenize 124 $replace($gettok($regml(1),2-,32),=",|,">,|,",|,$chr(44),.)
  var %w0 $iif($1 == af,AF: $2,DPS: $2 $+ $chr(44) Spd: $4)
  var %w1 %w0 - $iif(%SLASH,Slash: $v1 $+ $chr(44)) $iif(%STRENGTH,Strength: $v1 $+ $chr(44)) Quickness: %QUICKNESS $+ , $iif(%RES_CRUSH,Crush Resist: $v1 $+ $chr(44)) $iif(%HITPOINTS,Hits: $v1,Matter Resist: + $+ %RES_MATTER)
  msg %chan %c ( $+ $gettok($1-,-1,32) $+ ) - Lvl: %level $+ , Qual: %quality $+ , %w1 - %origin
}


WorldDMT
Joined: Nov 2009
Posts: 81
V
Babel fish
Offline
Babel fish
V
Joined: Nov 2009
Posts: 81
XML parser - very really.

I start to write it, but need ideas, how to get data from this tags? syntax?

I think rules: $xml(tag,subtag,subsubtag).param
Example:
$xml(tag) - returns <tag>_data_</tag>
$xml(tag,subtag) - returns <tag><subtag>_data_</subtag></tag>
$xml(tag,subtag).param - returns <tag><subtag param="_data_">blabla</subtag></tag>

Any ideas?

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
I'm pretty sure my code is to be improved (/fseek for the $reads or even $bfind on a pre-cached file in case of frequent uses of the trigger? hash table instead of global vars? neater regex? additional error checks? ...). But that method is inferior by all means.
The OP stated his file will contain "several thousand entries". I thus tried to reduce file accesses to a minimum. Now imagine some item located close to the end of his file - Do you really want to while-loop through several thousand items (each made of several lines)? It's not only a $read() of all the lines of virtually every item (and not, say, all <name>*</name>-lines), it's also the $regsubex it has to compute for each line... Sorry, but that's improvidence at it's best frown

Joined: Feb 2009
Posts: 133
C
Vogon poet
Offline
Vogon poet
C
Joined: Feb 2009
Posts: 133
you're right $read(file,w,<name> $+ $2- $+ </name>) avoids the first loop

this code was edited and the file has been replaced by items.xml
Code:
on *:text:*:#:{
  if ($strip($1) == !item) && ($2) {
    if ($read(items.xml,w,*<name> $+ $2- $+ </name>*)) wr $readn # $2-
    else msg # No such item found.
  }
}
alias -l wr {
  var %x $1,%chan $2,%c $3-
  while $read(items.xml,%x) {
    var %ex $v1
    if !$regex(%ex,</item>) {
      noop $regex(%ex,<(.+)>(.+)<)
      if ($gettok($regml(1),2,34)) var % $+ $v1 $regml(2)
      elseif ($regml(1)) var % $+ $v1 $regml(2)
    }
    else goto r
    inc %x
  }
  :r
  noop $regex($read(items.xml,$(},$(},$1))),\s(.+)<.+>)
  tokenize 124 $replace($gettok($regml(1),2-,32),=",|,">,|,",|,$chr(44),.)
  var %w0 $iif($1 == af,AF: $2,DPS: $2 $+ $chr(44) Spd: $4)
  var %w1 %w0 - $iif(%SLASH,Slash: $v1 $+ $chr(44)) $iif(%STRENGTH,Strength: $v1 $+ $chr(44)) Quickness: %QUICKNESS $+ , $iif(%RES_CRUSH,Crush Resist: $v1 $+ $chr(44)) $iif(%HITPOINTS,Hits: $v1,Matter Resist: + $+ %RES_MATTER)
  msg %chan %c ( $+ $gettok($1-,-1,32) $+ ) - Lvl: %level $+ , Qual: %quality $+ , %w1 - %origin
}

Last edited by chacha; 29/03/10 06:41 PM.

WorldDMT

Link Copied to Clipboard