Jump to content

[HELP] How to insert xml datas to a table?


Turbesz

Recommended Posts

I want insert datas from skins.xml to a table from which I can request data with loop, but does not working

This is my code: 

local tabla = {}

local xml = xmlLoadFile ( "skins.xml" )
local info = xmlFindChild ( xml, "skin", 0 )
local children = xmlNodeGetChildren(xml) 
if info then
    for i, node in ipairs(children) do
        local id = xmlNodeGetAttributes ( node, "id" )
        table.insert(tabla,id)
    end
end
xmlUnloadFile (xml)

function teszt()
    for k, v in ipairs(tabla) do
        outputChatBox(v)
    end
end
addCommandHandler("asd",teszt)

what wrong?

Link to comment

Nothing seems immediately wrong about this code (except the unnecessary use of xmlFindChild before xmlNodeGetChildren on the same xml node element). However, if this is client-side code, it's possible that the skins.xml file either isn't downloaded at all, or isn't ready to be read at the time the script begins execution (i.e. still downloading). To fix this, you should move the code that reads the XML into a function that's triggered upon the event onClientResourceStart. That is, if this is client-side code. Additionally, make sure that <file src="skins.xml" /> is in meta.xml otherwise the client never downloads the file.

You could additionally show us a well-formed sample/snippet of the skins.xml file, how it's structured, etc.

Edited by Addlibs
Link to comment
7 minutes ago, Addlibs said:

Nothing seems immediately wrong about this code (except the unnecessary use of xmlFindChild before xmlNodeGetChildren on the same xml node element). However, if this is client-side code, it's possible that the skins.xml file either isn't downloaded at all, or isn't ready to be read at the time the script begins execution (i.e. still downloading). To fix this, you should move the code that reads the XML into a function that's triggered upon the event onClientResourceStart. That is, if this is client-side code. Additionally, make sure that <file src="skins.xml" /> is in meta.xml otherwise the client never downloads the file.

You could additionally show us a well-formed sample/snippet of the skins.xml file, how it's structured, etc.

I already added the xml file in meta, but the outputchatbox part does not working, because i got this warning: "expected string at argument 1, got table"

This is the xml file (the default skins.xml from freeroam script):

	<group name="Special">
		<skin id="1" name="Truth" keywords="truth,male,white,hippie"/>
		<skin id="2" name="Maccer" keywords="maccer,male,white,:O"/>
		<skin id="265" name="Tenpenny" keywords="officer,tenpenny,male,black,cop"/>
		<skin id="266" name="Pulaski" keywords="officer,pulaski,male,white,cop"/>
		<skin id="267" name="Hern" keywords="officer,hern,male,latin"/>
		<skin id="268" name="Dwayne" keywords="dwayne,male,white,mechanic"/>
		<skin id="269" name="Big Smoke" keywords="big,smoke,male,fat,black,grove,street"/>
		<skin id="270" name="Sweet" keywords="male,sweet,johnson,black,grove,street"/>
		<skin id="271" name="Ryder" keywords="male,grove,street,black,ryder"/>
		<skin id="272" name="Forelli Guy" keywords="forelli,white,itallian"/>
		<skin id="290" name="Rose" keywords="rose,white,vice,city,lawyer"/>
		<skin id="291" name="Kent Paul" keywords="kent,paul,white,vice,city"/>
		<skin id="292" name="Cesar" keywords="cesar,lastin,male"/>
		<skin id="293" name="OG Loc" keywords="og,loc,black,rapper,grove,street,male"/>
		<skin id="294" name="Wuzi Mu" keywords="wuzi,mu,chinese,china,town,male"/>
		<skin id="295" name="Mike Toreno" keywords="mike,toreno,government,agent,white,male"/>
		<skin id="296" name="Jizzy" keywords="jizzy,club,pimp,black,male"/>
		<skin id="297" name="Madd Dogg" keywords="madd,dogg,black,rapper,male"/>
		<skin id="298" name="Catalina" keywords="catalina,liberty,city,latin,female"/>
		<skin id="299" name="Claude" keywords="calude,libery,city,gta,3,III,white,male,silent,protagonist"/>
		<skin id="300" name="Ryder" keywords="ryder,male,grove,street,black"/>
		<skin id="301" name="Ryder Robber" keywords="ryder,robber,male,grove,street,black"/>
		<skin id="302" name="Emmet" keywords="emmet,male,old,black,guns,weapon,dealer"/>
		<skin id="303" name="Andre" keywords="andre,white,male"/>
		<skin id="304" name="Kendl" keywords="kendl,johnson,black,female"/>
		<skin id="305" name="Jethro" keywords="jethro,male,white,mechanic"/>
		<skin id="306" name="Zero" keywords="zero,male,white,nerd"/>
		<skin id="307" name="T-bone Mendez" keywords="t,bone,mendez,t-bone,latin,male"/>
		<skin id="308" name="Sindaco Guy" keywords="sindaco,italian,male,white"/>
		<skin id="309" name="Janitor" keywords="janitor,casino,male,latin"/>
		<skin id="310" name="Big Bear" keywords="big,bear,druggie,grove,sreet"/>
		<skin id="311" name="Big Smoke Vest" keywords="big,smoke,male,fat,black,grove,street,ballas"/>
		<skin id="312" name="Physco" keywords="physco,army,camo,camoflage,male,white"/>
	</group>

 

Link to comment

For that structure you need to slightly modify your table - first, to loop through each group, and secondly, to prevent duplicate entries (I believe the freeroam skins XML can have the same skin under different groups)

local tabla = {}

function XmlToTable()
  local added = {} -- table to keep track of which skins were added to prevent duplicates
  local xml = xmlLoadFile("skins.xml") -- load the xml
  local groups = xmlNodeGetChildren(xml) -- the the xml root's children nodes
  if groups then
    for i, group in ipairs(groups) do -- loop the xml root's children nodes
      local skins = xmlNodeGetChildren(group) -- the the group's children nodes
      if skins then
        for j, skin in ipairs(skins) do -- loop the group's children nodes
          local id = tonumber(xmlNodeGetAttribute(skin, "id")) -- ensure you convert the string to a number, if impossible, a nil is returned - this is caught by the next if statement
          if id and not added[id] then -- if tonumber didn't fail and the id wasn't yet added
            table.insert(tabla, id) -- add it
            added[id] = true -- and prevent it from being added again
          end
        end
      end
    end
  end
  xmlUnloadFile(xml) -- unload now that we're done with this
end
addEventHandler("onClientResourceStart", resourceRoot, XmlToTable) -- if this script is clientside
addEventHandler("onResourceStart", resourceRoot, XmlToTable) -- if this script is serverside

function teszt()
  for k, v in ipairs(tabla) do
    outputChatBox(v)
  end
end
addCommandHandler("asd",teszt)

I've also noticed that "expected string at argument 1, got table" error is caused by storing tables within tabla instead of skin IDs - this originates from a typo in your code where you've written xmlNodeGetAttributes instead of xmlNodeGetAttribute.

Edited by Addlibs
  • Thanks 1
Link to comment
8 minutes ago, Addlibs said:

For that structure you need to slightly modify your table - first, to loop through each group, and secondly, to prevent duplicate entries (I believe the freeroam skins XML can have the same skin under different groups)


local tabla = {}

function XmlToTable()
  local added = {} -- table to keep track of which skins were added to prevent duplicates
  local xml = xmlLoadFile("skins.xml")
  local groups = xmlNodeGetChildren(xml)
  if groups then
    for i, group in ipairs(groups) do
      local skins = xmlNodeGetChildren(group)
      if skins then
        for j, skin in ipairs(skins) do
          local id = tonumber(xmlNodeGetAttribute(skin, "id")) -- ensure you convert the string to a number, if impossible, a nil is returned - this is caught by the next if statement
          if id and not added[id] then
            table.insert(tabla, id)
            added[id] = true
          end
        end
      end
    end
  end
  xmlUnloadFile (xml)
end
addEventHandler("onClientResourceStart", resourceRoot, XmlToTable) -- if this script is clientside
addEventHandler("onResourceStart", resourceRoot, XmlToTable) -- if this script is serverside

function teszt()
  for k, v in ipairs(tabla) do
    outputChatBox(v)
  end
end
addCommandHandler("asd",teszt)

I've also noticed that "expected string at argument 1, got table" error is caused by storing tables within tabla instead of skin IDs - this originates from a typo in your code where you've written xmlNodeGetAttributes instead of xmlNodeGetAttribute.

Thank youu, working fine ^^

Link to comment
3 hours ago, Addlibs said:

For that structure you need to slightly modify your table - first, to loop through each group, and secondly, to prevent duplicate entries (I believe the freeroam skins XML can have the same skin under different groups)


local tabla = {}

function XmlToTable()
  local added = {} -- table to keep track of which skins were added to prevent duplicates
  local xml = xmlLoadFile("skins.xml") -- load the xml
  local groups = xmlNodeGetChildren(xml) -- the the xml root's children nodes
  if groups then
    for i, group in ipairs(groups) do -- loop the xml root's children nodes
      local skins = xmlNodeGetChildren(group) -- the the group's children nodes
      if skins then
        for j, skin in ipairs(skins) do -- loop the group's children nodes
          local id = tonumber(xmlNodeGetAttribute(skin, "id")) -- ensure you convert the string to a number, if impossible, a nil is returned - this is caught by the next if statement
          if id and not added[id] then -- if tonumber didn't fail and the id wasn't yet added
            table.insert(tabla, id) -- add it
            added[id] = true -- and prevent it from being added again
          end
        end
      end
    end
  end
  xmlUnloadFile(xml) -- unload now that we're done with this
end
addEventHandler("onClientResourceStart", resourceRoot, XmlToTable) -- if this script is clientside
addEventHandler("onResourceStart", resourceRoot, XmlToTable) -- if this script is serverside

function teszt()
  for k, v in ipairs(tabla) do
    outputChatBox(v)
  end
end
addCommandHandler("asd",teszt)

I've also noticed that "expected string at argument 1, got table" error is caused by storing tables within tabla instead of skin IDs - this originates from a typo in your code where you've written xmlNodeGetAttributes instead of xmlNodeGetAttribute.

umm a last question: how to do it that puts the data in a separate table? because the xml file have a lot of groups, and I want to put the elements of each group in a separate table, i tried to do it but failed :/

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...