Ludeon Forums

Ludeon Forums

  • November 25, 2020, 07:33:41 PM
  • Welcome, Guest
Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1] 2 3 ... 11

Author Topic: XPATH surgery - Need help with xpath? post here.  (Read 22348 times)

skullywag

  • Global Moderator
  • Transcendent
  • ****
  • Posts: 5857
  • Engineer
    • View Profile
XPATH surgery - Need help with xpath? post here.
« on: June 02, 2017, 04:26:23 AM »

Hey all,

XPATH is kind of my thing and ive been slowly pumping out info about best practice when using it and some others have posted some info on my behalf, like the performance hit of using // over / (if the tree is known there is no need to use //). I could put down a tonne of info on using xpath 1.0 but thought it better to get real world examples, so with that in mind, if you have a RW xpath issue, post it here and ill try and get back to everyone with any answers or relevant knowledge on any xpath subjects. We can then collate these examples into the relevant stickied help threads etc. (This is my way of helping out "modding" while I cannot actually mod right now)

Fire away. :)
« Last Edit: June 02, 2017, 04:28:48 AM by skullywag »
Logged
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

Haplo

  • Global Moderator
  • Planetologist
  • ****
  • Posts: 2130
  • Shadow
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #1 on: June 02, 2017, 11:11:19 AM »

*Dialing Hotline*...ring, ring... ring, ring... "Hello, how may I help you?"

Hello XPath hotline.
I'd like to know from a professional side if my code is ok as it is.
It does work, but I'm just not sure if it's really the best way to do this?

So, here is my code:
Code: [Select]
<!-- Check if <comps /> exists. If not, add it -->
<Operation Class="PatchOperationSequence">
<success>Always</success>
<operations>
<li Class="PatchOperationTest">
<xpath>*/ThingDef[statBases/AccuracyLong > 0.05]/comps</xpath>
<success>Invert</success>
</li>
<li Class="PatchOperationAdd">
<xpath>*/ThingDef[statBases/AccuracyLong > 0.05]</xpath>
<value>
<comps />
</value>
</li>
</operations>
</Operation>

<!-- Find entries where AccuracyLong > 0.5 and add the new comp -->
<Operation Class="PatchOperationAdd">
<xpath>*/ThingDef[statBases/AccuracyLong > 0.05]/comps</xpath>
<value>
<li Class="WeaponRepair.CompProperties_WeaponRepairTwo2One">
<worktableDefs>
<li>TableMachining</li>
</worktableDefs>
<allowedDefSubName>Gun_</allowedDefSubName>
<compareQuality>true</compareQuality>
<jobDef>WeaponRepairTwo2One</jobDef>
<workTypeDef>Smithing</workTypeDef>
<maxRepair>0.95</maxRepair>
</li>
</value>
</Operation>

My questions: Is this useful or is there a better way to handle all available ranged weapons (only defs: Gun_*)?
Previously I tried ThingDef[defName="Gun_*"] but that didn't work and I didn't find an alternate call for that..

Thank you for your time ;D
Logged

AngleWyrm

  • Planetologist
  • ****
  • Posts: 1154
  • Refugee
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #2 on: June 02, 2017, 11:42:06 AM »

I recently came across a situation where I wanted to specify more than one selection criteria, as the item I was looking for had a composite key. What I was attempting to do looked like this (but it generated errors):

someTraitDefType[ defName="traitgroup" and subType="2" ]/recordSubThingy

Is there another approach, or some expected grammatical pattern to this approach?
Logged
My 5-point rating system: Yay, Kay, Meh, Erm, Bleh

skullywag

  • Global Moderator
  • Transcendent
  • ****
  • Posts: 5857
  • Engineer
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #3 on: June 03, 2017, 07:19:37 AM »

Haplo, would this help?

/ThingDef/defName[starts-with(., 'Gun_')]

To extend this with some further info starts-with is in xpath 1.0 but there is no ends-with, to do that you can use a mix of substring and string length:

substring(., string-length(.)- string-length('wordtofind') +1)

Hope i understood the issue properly. Let me know if i didnt.
Logged
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

skullywag

  • Global Moderator
  • Transcendent
  • ****
  • Posts: 5857
  • Engineer
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #4 on: June 03, 2017, 07:25:32 AM »

AngleWyrm:

//ThingDef[defName='whatever' and /ThingDef/someotherthing/text()='sometext']/whatever

Should work fine, let me know if that doesnt make sense. I think the issue here might have been that you werent supplying the second AND a path to thing you wanted it to find, it wuld have been expecting subtype to be at the same level as defname, i could be wrong but thats how it seems to me. If you can give the exact xml you have and what youre trying to target i can help further.
Logged
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

milon

  • 100% Nerd*
  • Global Moderator
  • Transcendent
  • ****
  • Posts: 3584
  • * Conditions may apply
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #5 on: June 03, 2017, 02:33:53 PM »

@Skully & Haplo, is there any reason that neither of you stickied this thread?

FYI, I un-stickied some old A12/A13 modding threads that haven't seen any action for a long time.  That should decrease our sticky-clutter.  :)

AngleWyrm

  • Planetologist
  • ****
  • Posts: 1154
  • Refugee
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #6 on: June 03, 2017, 09:24:23 PM »

Sometimes duplicate Add operation errors come up, and the situation in which they grow looks like this:

someDef[defName="aChosenThingy"]/entryToModify

The problem is that entryToModify may or may not exist in the record, and I want to add that entry if none currently exists.

Is there a best practice for this?
« Last Edit: June 04, 2017, 01:20:21 AM by AngleWyrm »
Logged
My 5-point rating system: Yay, Kay, Meh, Erm, Bleh

skullywag

  • Global Moderator
  • Transcendent
  • ****
  • Posts: 5857
  • Engineer
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #7 on: June 04, 2017, 02:32:54 AM »

AngleWyrm:

You need to test for its existence and add it if it doesnt exist, you can then add values to it in a further path if thats needed as well. as per:

Code: [Select]
<Operation Class="PatchOperationSequence">
  <success>Always</success>
  <operations>
    <li Class="PatchOperationTest">
      <xpath>//ThingDef[defName = "DiningChair"]/costList</xpath>
      <success>Invert</success>
    </li>
    <li Class="PatchOperationAdd">
      <xpath>//ThingDef[defName = "DiningChair"]</xpath>
      <value>
        <costList />
      </value>
    </li>
  </operations>
</Operation>

<Operation Class="PatchOperationAdd">
  <xpath>//ThingDef[defName = "DiningChair"]/costList</xpath>
  <value>
    <Cloth>5</Cloth>
  </value>
</Operation>
Logged
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

skullywag

  • Global Moderator
  • Transcendent
  • ****
  • Posts: 5857
  • Engineer
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #8 on: June 04, 2017, 02:35:58 AM »

Milon:

Stickied threads dont get seen much tbh, plus i was hoping the relevant people or myself would take from this thread and add to the tutorial threads that are about, 1 of which is stickied.
Logged
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

Sixdd

  • Colonist
  • ***
  • Posts: 249
  • Organ Grinder
    • View Profile
    • Sixdd6@GitHub
Re: XPATH surgery - Need help with xpath? post here.
« Reply #9 on: June 04, 2017, 02:43:45 PM »

Is there a way that I can make a sequence test not give an error when it fails to find the xpath? This is what I'm working with:
Code: [Select]
<Operation Class="PatchOperationSequence">
<success>Always</success>
<Operations>
<li Class="PatchOperationTest">
<xpath>*/ThingDef[defName="VG_Biofuel"]</xpath>
<success>Invert</success>
</li>
<li Class="PatchOperationInsert">
<xpath>*/ThingDef[defName="FueledGenerator"]/comps/li[@Class="CompProperties_Refuelable"]/fuelFilter/thingDefs</xpath>
<value>
<li>VG_Biofuel</li>
</value>
</li>
<li Class="PatchOperationInsert">
<xpath>*/ThingDef[DefName="FueledSmithy"]/comps/li[@Class="CompProperties_Refuelable"]/fuelFilter/thingDefs</xpath>
<value>
<li>VG_Biofuel</li>
</value>
</li>
<li Class="PatchOperationInsert">
<xpath>*/ThingDef[defName="Forge"]/comps/li[@Class="CompProperties_Refuelable"]/fuelFilter/thingDefs</xpath>
<value>
<li>VG_Biofuel</li>
</value>
</li>
</Operations>
</Operation>

This works with Vegetable Garden installed but I'm trying to make it work like an optional dependency, so if VG isn't installed it just ignores this operation.

EDIT: Nevermind, I commented the success element from the test operation and now it does the test without giving an error if it fails. Yay!
« Last Edit: June 04, 2017, 03:43:50 PM by Sixdd »
Logged

delheit

  • Drifter
  • **
  • Posts: 50
  • Refugee
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #10 on: June 09, 2017, 12:20:42 AM »

I hope you can help I can't figure out what's wrong.

This works fine
Code: [Select]
<Operation Class="PatchOperationReplace">
    <xpath>/ThingDefs/ThingDef[defName = "MineableSteel"]/building/mineableYield</xpath>
    <value>
                <mineableYield>40</mineableYield>
    </value>
</Operation>

But this does not
Code: [Select]
<Operation Class="PatchOperationReplace">
    <xpath>/ThingDefs/ThingDef[defName = "Wall"]/costStuffCount</xpath>
    <value>
                <costStuffCount>10</costStuffCount>
    </value>
</Operation>

I get this error on the second one.

Quote
Patch operation Verse.PatchOperationReplace(/ThingDefs/ThingDef[defName = "Wall"]/costStuffCount) failed

I have tried changing some things around like ThingDefs to Buildings or ThingDefs_Buildings but honestly both examples look so similar I am surprised it's not working the way it is.

Thank You

Update: I got it to work but I think I'm not suppose to do it this way.

Code: [Select]
<xpath>//ThingDef[defName = "Wall"]/costStuffCount</xpath>
« Last Edit: June 09, 2017, 12:56:51 AM by delheit »
Logged

Sixdd

  • Colonist
  • ***
  • Posts: 249
  • Organ Grinder
    • View Profile
    • Sixdd6@GitHub
Re: XPATH surgery - Need help with xpath? post here.
« Reply #11 on: June 09, 2017, 05:02:46 AM »

Yeah don't use the // instead try this

Code: [Select]
<xpath>*/ThingDef[defName = "Wall"]/costStuffCount</xpath>
The * at the beginning tells it to check all root tags where as the // tells it to check EVERY tag, even non root tags.

EDIT: To elaborate more, anywhere you place a * it will match "anything"
« Last Edit: June 09, 2017, 05:05:28 AM by Sixdd »
Logged

skullywag

  • Global Moderator
  • Transcendent
  • ****
  • Posts: 5857
  • Engineer
    • View Profile
Re: XPATH surgery - Need help with xpath? post here.
« Reply #12 on: June 09, 2017, 05:52:48 AM »

Yep as sixdd has rightly stated, we as people that know the structure of the xml should never have a need for //

however in terms of your second patch costStuffCount doesnt exist on mineableSteel does it? thats what you are adding.
Logged
Skullywag modded to death.
I'd never met an iterator I liked....until Zhentar saved me.
Why Unity5, WHY do you forsake me?

dburgdorf

  • Planetologist
  • ****
  • Posts: 1380
  • The dorfiest of dorf modders.
    • View Profile
    • My Facebook page. *Shrug* It's the only Web site I have these days.
Re: XPATH surgery - Need help with xpath? post here.
« Reply #13 on: June 09, 2017, 11:16:10 AM »

I am virtually certain the answer to this question is "no," but I'll ask just for the sake of asking. Is there any way to use patching to create an entirely new def? Specifically, I'm wondering if there's any way to have a mod that adds plants also create seed defs if (and only if) "Seeds Please!" is in use, to avoid the need to have a secondary mod add them.
Logged
- Rainbeau Flambe (aka Darryl Burgdorf) -
Old. Short. Grumpy. Bearded. "Yeah, I'm a dorf."



Buy me a Dr Pepper?

Sixdd

  • Colonist
  • ***
  • Posts: 249
  • Organ Grinder
    • View Profile
    • Sixdd6@GitHub
Re: XPATH surgery - Need help with xpath? post here.
« Reply #14 on: June 09, 2017, 12:01:17 PM »

That is actually possible. Basically (in my understanding) as long as you have a root node to build off of you can add anything you like using an Add or Insert operation.

Also you can use a reference to a ThingDef in the mod you want to check for like this:

Code: [Select]
<Operation Class="PatchOperationSequence">
<success>Always</success>
<Operations>
<li Class="PatchOperationTest">
<xpath>*/ThingDef[defName="EXP_Copper"]</xpath>
</li>
etc...

This returns true if the ThingDef with defName "EXP_Copper" exists. From there you just put more <li Class="someclass"> elements in for each operation you want to do.

Also I believe that Cupro has some kind of thing that checks for a mod name rather than checking for a defName.
« Last Edit: June 09, 2017, 12:11:00 PM by Sixdd »
Logged
Pages: [1] 2 3 ... 11