[TUTORIAL] XML Patch Guide

The place to discuss scripting and game modifications for X Rebirth.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader » Sun, 20. Jul 14, 09:18

you can either use the method mentioned here before for adressing the nth node (here the 2nd):
//pointlist/point[2]/@r

or you find an unique attribute in them, which does not have to be the same as the one you want to modify (the 2nd from your example here, too ^^):
//pointlist/point[@z='-3094.52']/@r

alternatively try if the game now supporsts the msel extension, although i doubt it does..
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

lhotski
Posts: 82
Joined: Thu, 10. Oct 13, 17:10
x3ap

Post by lhotski » Sun, 20. Jul 14, 11:01

Thank you, UniTrader!

In such cases other ways for replace are too bulky IMHO. :( This is just example which not very often used, perhaps.

msel selector is not supported here as you said:

Code: Select all

<replace msel="//point/@r">500</replace>

[=ERROR=] Missing 'sel' attribute in 'replace' node in patch file 'extensions\simplehack\libraries\targetpoints.xml'. Skipping node.

w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans » Sun, 21. Dec 14, 18:45

Probably a dumb question, but if I started with this:

Code: Select all

<root>
  <bar>
    <foo a="1"/>
    <foo a="2"/>
  </bar>
</root>
and wrote this:

Code: Select all

<diff>
  <replace sel="//bar">
    <bar>

    </bar>
  </replace>
</diff>
would it output this?

Code: Select all

<root>
  <bar>
  </bar>
</root>
or this?

Code: Select all

<root>
  <bar>
    <foo a="1"/>
    <foo a="2"/>
  </bar>
</root>
edit: forgot a <bar></bar>

User avatar
Litauen
Posts: 193
Joined: Fri, 22. Nov 13, 21:09
xr

Post by Litauen » Fri, 13. Feb 15, 23:23

Need help.

File /md/NPC_Staff.xml

Code: Select all

<cue name="SectionHandler" instantiate="true">
..
<actions>
..
<do_elseif value="event.param == 'cStaff_move'">
...
  <dismiss_control_entity actor="$actor" object="$actor.container" />
</do_elseif>
I need this

Code: Select all

  <dismiss_control_entity actor="$actor" object="$actor.container" />
to be like this:

Code: Select all

  <do_if value="$actor.iscontrolentity">			
    <dismiss_control_entity actor="$actor" object="$actor.container" />
  </do_if>
Tried, does not work:

Code: Select all

<replace sel="//dismiss_control_entity[@actor='$actor']" >
<replace sel="*/dismiss_control_entity[@actor='$actor']" >
<replace sel="//dismiss_control_entity" >
<replace sel="*/dismiss_control_entity" >
<replace sel='//cue[@name="SectionHandler"]/actions/do_elseif[@value="event.param == 'cStaff_move'"]/dismiss_control_entity' >
<replace sel='//cue[@name="SectionHandler"]/actions/do_elseif[@value="event.param == /'cStaff_move/'"]/dismiss_control_entity'  >
Changed quotes from ' to " and vice versa, etc etc etc

Nothing works. Please help.

w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans » Fri, 13. Feb 15, 23:31

Hey Litauen,

only way I found to reliably do that is to do a <remove ... /> and <add ... />

Code: Select all

<remove sel="//dismiss_control_entity[@object='$actor.container']"/>

<add sel="[your xpath]">
  <do_if value="$actor.iscontrolentity">         
    <dismiss_control_entity actor="$actor" object="$actor.container" />
  </do_if>
</add>

User avatar
Litauen
Posts: 193
Joined: Fri, 22. Nov 13, 21:09
xr

Post by Litauen » Sat, 14. Feb 15, 11:51

Thank you. This seems to work:

Code: Select all

	<remove sel="//dismiss_control_entity[@object='$actor.container']"/>
	<add sel='//cue[@name="SectionHandler"]/actions/do_elseif[@value="event.param == &apos;cStaff_move&apos;"]' >
		<do_if value="$actor.iscontrolentity">			
			<dismiss_control_entity actor="$actor" object="$actor.container" />
		</do_if>
	</add>
&apos; covers single quotes inside string.

w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans » Sat, 14. Feb 15, 11:55

Litauen wrote:&apos; covers single quotes inside string.
Oh cool. That I did not know. Thanks!

edit: Just noticed that this thread isn't stickied anymore. Is there a new XML Patch guide coming up?

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader » Sat, 14. Feb 15, 12:36

its now linked in the Stickied Topic [Index] X Rebirth Tools, Tutorials and Resources because too many Stickies clutter up the top of the Forum - less is more here ;)
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans » Sat, 14. Feb 15, 12:39

Agreed. Thanks for taking the time to explain.

User avatar
nidaren
Posts: 66
Joined: Wed, 27. Nov 13, 14:33
x4

Post by nidaren » Tue, 31. Mar 15, 20:52

Hey Everyone,

I have a question in regards to what is the best solution to use in the case of:

add but only if such node does not exist in xml and skip if it does, is that possible via diff ?

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader » Tue, 31. Mar 15, 21:18

<add sel="/aiscript[not(interrupts)]"><interrupts/></add>
should do the trick - will result in an entry to the debuglog if that node already exists, but but that should be fine right? ;)

(already used a case where this is useful for compatibility as example ^^)
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

User avatar
nidaren
Posts: 66
Joined: Wed, 27. Nov 13, 14:33
x4

Post by nidaren » Wed, 1. Apr 15, 01:26

Hey Uni,

Thanks a lot - that is what I was looking for :) Indeed, it is not a problem if it does input to the log, as long as it does not create a duplicate entry.

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader » Mon, 6. Apr 15, 20:14

lhotski wrote:Thank you, UniTrader!

In such cases other ways for replace are too bulky IMHO. :( This is just example which not very often used, perhaps.

msel selector is not supported here as you said:

Code: Select all

<replace msel="//point/@r">500</replace>

[=ERROR=] Missing 'sel' attribute in 'replace' node in patch file 'extensions\simplehack\libraries\targetpoints.xml'. Skipping node.
i just had such a case where i didnt want to crawl through the files and find apporiate xpaths for each, this worked fine - i just needed one line of it per Entry to be replaced:
<replace sel="(//@*[. = "player.copilot"])[1]">md.$Copilot</replace>

or more general:
sel="(//msel_path)[1]"
resolves to the first ocurrence of the msel path - if you delete or change nodes in such a way that the Path doesnt apply anymore after that you can have an msel-equivalent by C&Ping the Line for each ocurrense ;) -> just write proper Comments if you do that so others understand the intention. (if the Path doesnt change count the Number in square brackets up ;) )
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

kelmenwong
Posts: 197
Joined: Sat, 17. Mar 12, 17:40
x3tc

Post by kelmenwong » Tue, 4. Aug 15, 13:01

is there a doc/ref to list what are the possible options/values for "pos" attribute?

like i want to insert before the end of the node, or as last child.

w.evans
Posts: 2963
Joined: Tue, 18. Nov 14, 16:23
x4

Post by w.evans » Tue, 4. Aug 15, 13:11

kelmenwong wrote:is there a doc/ref to list what are the possible options/values for "pos" attribute?
There's a list of valid pos arguments (is that the right term?) in the OP. Don't know how complete it is, though.
kelmenwong wrote:like i want to insert before the end of the node, or as last child.
If I remember correctly, that's default.

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader » Tue, 4. Aug 15, 17:17

Yes, end of selected node is default

Other options if //foo was selected

<before/>
<foo>
<prepend/>
.....
<default/>
</foo>
<after/>
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

jth
Posts: 296
Joined: Tue, 3. Jan 06, 23:31
x3

Post by jth » Thu, 12. Nov 15, 13:47

I thought that I might share something that I came up with yesterday to document and debug patch statements

My Format Thousands mod does a shed load of individual line patching and it was getting very difficult to work out which line I was having trouble with especially running it on 3.61 and 4.00 beta 2 (where a load of line patches are meant to not match)

What I needed was some suitable comments. I Googled for comments in XPath 2 and that is possible to do but they don't appear when you get
Cannot match path ..... . Skipping node. errors

I came up with the idea of adding a ['this is a comment'] condition to the select part of each line immediately after the name of the script

['this is a comment'] happens to evaluate to true, so it has no effect on the result of the XPath expression

Code: Select all

  <remove sel="/mdscript[@name='Notifications']/cues/library[@name='FormatThousands' and @version < 2]"/>
to

Code: Select all

  <remove sel="/mdscript[@name='Notifications']['FormatThousands library already v2']/cues/library[@name='FormatThousands' and @version < 2]"/>
so I now get an error of

Cannot match path '/mdscript[@name='Notifications']['FormatThousands library already v2']/cues/library[@name='FormatThousands' and @version < 2]' in patch file 'extensions\format_thousands\md\notifications.xml'. Skipping node.

That tells me what patch file Notifications to look at and what the patch does so that I can then make a judgement on whether its an error or working as intended. Putting the comment up the front means that you don't have to scroll to the right to see it.

I have added in messages like ['Money formatting - v3.61 and older'] and even ['$AMOUNT$ formatting 302 - all'] so that I can zero in quickly on the right line

Its much easier to see the wood from the trees now :)

jth

pref
Posts: 5589
Joined: Sat, 10. Nov 12, 17:55
x4

Post by pref » Thu, 12. Nov 15, 15:10

I have a problem i can't seem to fix, keep getting cannot match path errors.

This diff does not execute:

Code: Select all

  
<?xml version="1.0" encoding="UTF-8"?>
<diff>
  <add sel="//add_npc_line[@line='13']" type="@hidechoices">false</add>
  <add sel="//add_npc_line[@line='3031']" type="@hidechoices">false</add>
  <add sel="//add_npc_line[@line='3001']" type="@hidechoices">false</add>
</diff>
Even though the xml im patching (GM_Defend_Station) looks like this (13 and 3031):

Code: Select all

                  <actions>
                    <do_if>
                      ...
                    <do_elseif value="event.param == 'c_offer_accept'">
                      <add_npc_line line="3031"/>
                      <signal_cue cue="MissionAccepted"/>
                    </do_elseif>
                    <!--Decline case-->
                    <do_elseif value="event.param == 'c_offer_decline'">
                      <do_if value="$EventOffer">
                         ...
                      </do_if>
                      <do_else>
                        <add_npc_line line="13" comment="Whatever."/>
                        <!-- restart Accepted event listener -->
                        <reset_cue cue="ShowOffer"/>
                      </do_else>
And this (3001):

Code: Select all

                  <actions>
                    <add_conversation_view view="facenormal"/>
                    <do_if value="event.name" exact="'event_conversation_started'">
                      <add_npc_line line="3001"/>
                    </do_if>
13 and 3031 fails, while 3001 executes properly.
What am i missing? Any help appreciated!

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Post by UniTrader » Thu, 12. Nov 15, 16:09

I think this XPath resolves to two possible nodes (the line 13 and 1031 are at least two times in the file) - find a way to address them individually

@jth
useful idea - especially if some paths fail for version or mod compatibility stuff :)
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

pref
Posts: 5589
Joined: Sat, 10. Nov 12, 17:55
x4

Post by pref » Thu, 12. Nov 15, 19:34

Only 3 occurrances of the <add_npc_line /> node, no dupes.
Any idea appreciated.

Post Reply

Return to “X Rebirth - Scripts and Modding”