mIRC Homepage
Posted By: Borg8401 Question about MIRC and XML - 25/03/10 11:18 PM
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!
Posted By: Riamus2 Re: Question about MIRC and XML - 26/03/10 01:11 AM
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.
Posted By: Borg8401 Re: Question about MIRC and XML - 27/03/10 09:27 PM
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
}
Posted By: chacha Re: Question about MIRC and XML - 27/03/10 11:47 PM
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(...)
Posted By: Horstl Re: Question about MIRC and XML - 27/03/10 11:54 PM
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
Posted By: chacha Re: Question about MIRC and XML - 28/03/10 08:11 PM
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
}
Posted By: Voglea Re: Question about MIRC and XML - 29/03/10 02:28 AM
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?
Posted By: Horstl Re: Question about MIRC and XML - 29/03/10 01:04 PM
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
Posted By: chacha Re: Question about MIRC and XML - 29/03/10 05:42 PM
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
}
© mIRC Discussion Forums