• If you have a mod, tool or prefab, please use the Resources section. Click Mods at the top of the forums.

Using XSLT to help Modding (changing XMLs, producing information/web pages)

dcsobral

New member
It seems most people are relying on hand editing XML files. I'd like to call attention to something that was designed explicitly to manipulate XML content: XSLT. This is very different from doing a search&replace, as XSLTs understand the structure of XML and work with it.

The way XSLT works is the you write a template for the transformation you want (an XSL file), then use an XSLT processor to apply the template to an XML file. The output can be pretty much anything: text, and html page, or another XML.

I'll put here some examples. They are all using a processor called XML Starlet, which is rather dated but available for Windows, Mac and Linux, and easy to use.

Do Not Sell: modifies blocks.xml or items.xml to make all craftable items non-sellable. Example:

Code:
Daniel@GAMING C:\Program Files (x86)\Steam\steamapps\common\7 Days to Die Dedicated Server\Data\Config
> xml tr doNotSell.xsl items.xml > items2.xml
Changing explicitly sellable itemclubIron to false
Changing explicitly sellable itemclubBarbed to false
Changing explicitly sellable itemclubSpiked to false

Daniel@GAMING C:\Program Files (x86)\Steam\steamapps\common\7 Days to Die Dedicated Server\Data\Config
> xml tr doNotSell.xsl blocks.xml >blocks2.xml
Diff of the changes:

Code:
Daniel@GAMING C:\Program Files (x86)\Steam\steamapps\common\7 Days to Die Dedicated Server\Data\Config
> git diff items.xml items2.xml
diff --git a/items.xml b/items2.xml
index 201812b..d7a5188 100644
--- a/items.xml
+++ b/items2.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<!-- Forge weight: We have auto-scaling based on resources IF there is a recipe for the item.

Item ID ranges:       Master items (if applicable) are listed at the start of their ID range.
@@ -84,7 +84,7 @@ Mesh files no longer used:
       <property name="Meshfile" value="Items/Weapons/Melee/Club/Club_Wood_RefinedPrefab"/>
       <property name="Material" value="metal"/>
       <property name="EconomicValue" value="100"/>
-       <property name="SellableToTrader" value="true"/>
+       <property name="SellableToTrader" value="false"/>
       <property name="RepairTools" value="scrapIron"/>
       <property name="DegradationBreaksAfter" value="false"/>
       <property name="SoundJammed" value="ItemNeedsRepair"/>
@@ -109,7 +109,7 @@ Mesh files no longer used:
       <property name="Meshfile" value="Items/Weapons/Melee/Club/Club_Wood_BarbedPrefab"/>
       <property name="RepairTools" value="forgedIron"/>
       <property name="EconomicValue" value="192"/>
-       <property name="SellableToTrader" value="true"/>
+       <property name="SellableToTrader" value="false"/>
       <property class="Action0"> <!-- AttackAction -->
               <property name="Stamina_usage" value="6.5"/>
               <property name="Delay" value="1.15"/>
@@ -133,7 +133,7 @@ Mesh files no longer used:
       <property name="Meshfile" value="Items/Weapons/Melee/Club/Club_Wood_SpikedPrefab"/>
       <property name="RepairTools" value="forgedIron"/>
       <property name="EconomicValue" value="300"/>
-       <property name="SellableToTrader" value="true"/>
+       <property name="SellableToTrader" value="false"/>
       <property class="Action0"> <!-- AttackAction -->
               <property name="Stamina_usage" value="8.5"/>
               <property name="Buff" value="bleeding,criticalBlunt"/>
@@ -185,6 +185,7 @@ Mesh files no longer used:
       <property name="Group" value="Ammo/Weapons,Tools/Traps"/>
       <property name="ActionSkillGroup" value="Blunt Weapons"/>
       <property name="CraftingSkillGroup" value="craftSkillWeapons"/>
+       <property name="SellableToTrader" value="false"/>
</item>
...

Unused Icons: List all icons not used by the UI. This doesn't cover all cases, as it was "good enough". Example:

Code:
Daniel@GAMING D:\Games\7D2D\Ravenhearst\7_Day_Horde_Edition\Data\Config
> xml ls ../../Mods/SDX/ItemIcons/ | xml tr unusedIcons.xsl
AdvancedSplint.png
AdvancedSplintIcon.png
ammoLoader.png
...
Food Table: This one is massive, and I'd make it much simpler on rewrite, I just picked it because it takes input from multiple sources. Here is a sample output, using Ravenhearst's 2.2 data as input.

 
That's good idea for expert person. Actually, there is the SDX, which search subject node via XPath, edit via 5 operations.

I'm curious about processing time.

I haven't used it but how is that?

 
That's good idea for expert person. Actually, there is the SDX, which search subject node via XPath, edit via 5 operations.
But that's still manual, right? You can do it easily, but you have to do it every time, instead of having a scripted query/change you can reapply at will?

I'm curious about processing time.

I haven't used it but how is that?
That depends on the complexity. It's usually pretty fast to almost instantaneous, but if you have to do a lot of cross-references, it can be slower.

For example, on a previous version of the loot probability I looked up the localization of blocks and entities associated with a loot table for every entry in that loot table, despite the fact that all entries point to the same thing, which was really slow. Now it looks it up only once, so it's reasonably fast. I could improve it further first saving that lookup for every block/entity with a loot list, and then referring to those results, but it takes a few seconds to generate the loot table, so it isn't worth the effort.

 
Back
Top