selecting from multiple xml elements query

Freeform discussion about anything related to modding Transcendence.
Post Reply
relanat
Militia Captain
Militia Captain
Posts: 700
Joined: Tue Nov 05, 2013 9:56 am

Tue Feb 05, 2019 4:48 am

This is some of the XML from &ssStartonEridani;.

It is 2 of 5 <Group> subelements from an <Orbitals> block.

Code: Select all

<!-- Hagaron
	Another inner world -->

<Group distance="160">
	<Primary>
		<Station type="&stDesertTerrestrialSizeH;" name="Hageron" showOrbit="true"/>
	</Primary>

	<Orbitals distance="1d8+8" angle="random">
		<Lookup table="Stations1" probability="80"/>
	</Orbitals>

</Group>

<!-- Raphael -->

<Group distance="270">
	<Primary>
		<Station type="&stRockyPlanetoidSizeG;" name="Raphael" showOrbit="true"/>
	</Primary>

	<Orbitals distance="1d8+8" angle="random">
		<Lookup table="Stations1" probability="80"/>
	</Orbitals>
	NOTE: <Trojan/AntiTrojan> deleted from here.
</Group>
Continual use of 'xmlGetSublement' will select the <Orbitals> element.
It is more difficult to select one of the <Group> blocks from the other four.

Code to get this far and set a list of all 5 <Group> subelements:

Code: Select all

	;All the XML.
(setq EridaniXML (typGetXML &ssStartonEridani;))
	;The SystemGroup XML.
(setq sysXML (xmlGetSubElement EridaniXML "SystemGroup"))
	;The Orbitals XML.
(setq orbXML (xmlGetSubElement sysXML "Orbitals"))
	;A list of "Group" XML subelements from the "Orbitals" XML.
(setq groupList (xmlGetSubElementList orbXML "Group"))
So 'groupList' is a list of the 5 <Group> XML blocks including the 2 above.
I've used the code below successfully to get the "distance="160"" element but it seems a bit long-winded.

Code: Select all

	;Set the string to find in 'groupList'.
(setq find160 "&lt;Group distance=\"160\"&gt;")
	;Filter 'groupList' to select the relevant "Group" XML.
(setq group160XML (@ (filter groupList theXML (find theXML find160)) 0))
Ideally there would be a way to filter using the 'distance' attribute. But I don't know if this is possible. Can one of the 'xml' functions be used somehow to select for '160'? Or is there another prefered way of doing this? Something that returned the index would be good.
Last edited by relanat on Thu Feb 07, 2019 1:30 am, edited 1 time in total.

NMS
Militia Captain
Militia Captain
Posts: 512
Joined: Tue Mar 05, 2013 8:26 am

Wed Feb 06, 2019 5:35 am

Something like this?

(@ (filter groupList theGroup (eq 160 (xmlGetAttrib theGroup 'distance))) 0)

relanat
Militia Captain
Militia Captain
Posts: 700
Joined: Tue Nov 05, 2013 9:56 am

Thu Feb 07, 2019 1:29 am

That will do it. Thanks.

But due to my poor communication skills.
What I was really checking for was some way of using 'xmlGetSubElement' ot 'xmlGetAttrib' or whichever function to select from 'orbXML'.
I wasn't sure if there was some sort of criteria that could be used, maybe like:

Code: Select all

(xmlGetSubElement orbXML {distance:160})
or something like that which selected from multiple elements of the same name. Rather than creating the list then filtering it.
Or some sort of similar code which returned the index of the desired subElement. That would be easier too.

It wouldn't be the first time I was clueless about how to do something that was really easy.
But the code you provided is excellent. Much easier than text formating xml!
Last edited by relanat on Sun Feb 10, 2019 12:57 pm, edited 1 time in total.

NMS
Militia Captain
Militia Captain
Posts: 512
Joined: Tue Mar 05, 2013 8:26 am

Thu Feb 07, 2019 4:32 am

No, you can only select subelements by tag or index.

relanat
Militia Captain
Militia Captain
Posts: 700
Joined: Tue Nov 05, 2013 9:56 am

Tue Mar 05, 2019 1:35 am

The code works well. Thanks.
You can select for either numbers, number ranges or dice ranges.
These examples all work: 160, "75-85" or "1d2". As does "*archipelago" for 'locationCriteria' attributes.


Of note if searching by string as in the first post is the need to take into account the shuffling of attribute order done by the game.

An example. When trying to get this element from the &ssPointJuno; code:

Code: Select all

<Orbitals distance="75-85" angle="random">
	<Group>
		<Primary>
			<Station type="&stVolcanicTerrestrialSizeH;" name="Zheling I"	showOrbit="true"/>
		</Primary>

		<Orbitals distance="2d6+10" angle="random">
			<Lookup table="StargateOutbound"/>
		</Orbitals>
	</Group>
</Orbitals>
searching for the XML string as it appears in the code above

Code: Select all

(setq stringToFind "&lt;Orbitals distance=\"75-85\" angle=\"random\"&gt;")
(setq orbitals75XML @ (filter orbitalsList theXML (find theXML stringToFind)) 0))
returns Nil.

What is happening is the attributes are in a different order inside the game.
Using typGetXML for the same "Orbitals" element and printing it to the log shows the XML as

Code: Select all

<Orbitals angle="random" distance="75-85">
The game for some reason changes the order. Searching for this string does return the desired XML element.
So if searching by string it will probably be necessary to manually get the XML to find which order the game places the attributes in and use that string.

But it is easier to use NMS' code above.

More examples.
The first code here is as it appears in &ssHeretic in Heretic.xml.

Code: Select all

<Orbitals count="3d2" distance="65-80" angle="minSeparation:10">
It shows as

Code: Select all

<Orbitals count="3d2" angle="minSeparation:10" distance="65-80">
after using 'typGetXML' to get the same code so need to search for this as a string. Not how it appears in the first example.

I went looking for XML with 4 attributes and found this in the &stAresCommune XML "Satellites" element.

Code: Select all

<Orbitals levelFrequency="----- cccur ----- -----" count="2d4" distance="12" angle="equidistant">
It shows as:

Code: Select all

<Orbitals count="2d4" levelFrequency="----- cccur ----- -----" angle="equidistant" distance="12">
but I can't pick any pattern from these few examples.

Post Reply