All Things WinBatch > WinBatch

Read data from an XML file.

(1/2) > >>

mlburgoon71:
I am trying to write a program to help me with modding some games I play.  I am struggling with figuring out the best way to read in values from the default .xml file, provided by the game, so I can change and manipulate them.  small snippet Example below of the xml file.

But what I want to be able to do is pull the value like so..

eg =  (some command) (/entity_classes/entity_class(@name="zombieNurseFeral")/property(@name="ExperienceGain")

how is this possible to do??  been looking at the wbOmnibus extender and it sounded promising.  but having issues getting it to work. I am hoping I don't have to create my own parser to do this.....

excerpt from the game .xml.
<entity_classes>
<entity_class name="zombieNurse" extends="zombieTemplateMale">
   <property name="Tags" value="entity,zombie,walker"/>
   <property name="Mesh" value="#Entities/Zombies?Prefabs/ZNurse.prefab"/>
   <property name="SoundRandom" value="Enemies/Base_Zombie_Female/zombiefemaleroam"/>
   <property name="SoundAlert" value="Enemies/Base_Zombie_Female/zombiefemalealert"/>
   <property name="SoundAttack" value="Enemies/Base_Zombie_Female/zombiefemaleattack"/>
   <property name="SoundHurt" value="Enemies/Base_Zombie_Female/zombiefemalepain"/>
   <property name="SoundDeath" value="Enemies/Base_Zombie_Female/zombiefemaledeath"/>
   <property name="SoundSense" value="Enemies/Base_Zombie_Female/zombiefemalesense"/>
   <property name="AvatarController" value="AvatarZombie01Controller"/>
   <property name="ModelType" value="Standard"/>
   <property name="WalkType" value="7"/>
   <property name="Mass" value="130"/>
   <property name="RootMotion" value="true"/>
   <property name="HasDeathAnim" value="true"/>
   <property name="AIPathCostScale" value=".5, .65"/>
   <property name="DanceType" value="2" />

   <!-- Gameplay zombieNurse -->
   <property name="MoveSpeedAggro" value="0.3, 1.35"/> <!-- slim, regular -->
   <property name="HandItem" value="meleeHandZombie01"/>
   <effect_group name="Base Effects">
      <passive_effect name="HealthMax" operation="base_set" value="125"/>
   </effect_group>
</entity_class>

<entity_class name="zombieNurseFeral" extends="zombieNurse">
   <property name="Tags" value="entity,zombie,walker,feral"/>
   <property name="Mesh" value="#Entities/Zombies?Prefabs/ZNurseFeral.prefab"/>

   <!-- Gameplay zombieNurseFeral -->
   <property name="DismemberMultiplierHead" value=".7"/><property name="DismemberMultiplierArms" value=".7"/><property name="DismemberMultiplierLegs" value=".7"/><!-- Feral -->
   <property name="PainResistPerHit" value=".7"/><!-- Feral -->
   <property name="MoveSpeedAggro" value="0.6, 1.45"/> <!-- slim, feral -->
   <property name="JumpMaxDistance" value="4.6, 5"/>
   <property name="HandItem" value="meleeHandZombieFeral"/>
   <property name="ExperienceGain" value="750"/><!-- XP grunt feral -->
   <property name="LootDropProb" value=".03"/> <!-- Feral -->

   <effect_group name="Base Effects">
      <passive_effect name="HealthMax" operation="base_set" value="237"/>
      <!--<passive_effect name="EntityDamage" operation="perc_add" value="0"/>--> <!-- Feral damage -->
   </effect_group>
</entity_class>

<entity_class name="zombieNurseRadiated" extends="zombieNurseFeral">
   <property name="Tags" value="entity,zombie,walker,feral,radiated"/>
   <property name="Mesh" value="#Entities/Zombies?Prefabs/ZNurseRadiated.prefab"/>

   <!-- Gameplay zombieNurseRadiated -->
   <property name="DismemberMultiplierHead" value=".4"/><property name="DismemberMultiplierArms" value=".4"/><property name="DismemberMultiplierLegs" value=".4"/><!-- Radiated -->
   <property name="PainResistPerHit" value=".9"/><!-- Radiated -->
   <property name="ExperienceGain" value="1200"/><!-- XP grunt radiated -->

   <effect_group name="Base Effects">
      <passive_effect name="HealthMax" operation="base_set" value="451"/>
      <!--<passive_effect name="EntityDamage" operation="perc_add" value="0"/>--><!-- Feral damage -->
      <triggered_effect trigger="onOtherDamagedSelf" action="ModifyCVar" target="self" cvar="RadiatedRegenAmount" operation="set" value="4"/>
      <triggered_effect trigger="onOtherDamagedSelf" action="AddBuff" target="self" buff="buffRadiatedRegen"/>
   </effect_group>
</entity_class>
</entity_classes>

stanl:
I'm sure Jim would like to hear more specifics about issues you encountered using his Extender. I would think you could write your own parser using the WB CLR and .net assemblies. But you are also interested in changing 'values' [if I read your initial post correctly] which would imply an xml editor of sorts. Thanks for providing the sample .xml - can take a stab at it.


[EDIT]
from Tech DB


https://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WinBatch/dotNet/System_XML+ReadXmlFile~Sample.txt

JTaylor:
I will try to take a look soon.  If you are wanting to change your XML, my extender is not a good choice though.  Perhaps the following will help provide a solution.

Jim


--- Code: Winbatch ---

;https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms754585(v=vs.85)


#DefineFunction Load_MSXMLData(xtxt)

  MSXML                    = ObjectOpen("MSXML2.DOMDocument.6.0")
  MSXML.Async              = "False"
  MSXML.preserveWhiteSpace = "False"
  MSXML.validateOnParse    = "False"
  MSXML.resolveExternals   = "False"

  Loaded = MSXML.LoadXML(xtxt)
  If !Loaded Then
 
    If !IsDefined(stxt) Then stxt = ""
    xPE = MSXML.parseError
    strErrText = "Your XML Document failed to load due the following error.":@CRLF:"Error #: ":xPE.errorCode:": ":xPE.reason:"Line #: ":xPE.Line:@CRLF:"Line Position: ":xPE.linepos:@CRLF:"Position In File: ":xPE.filepos:@CRLF:"Source Text: ":xPE.srcText:@CRLF:"Document URL: ":xPE.url
    clipput(strErrText)
    Message("Error",strErrText)
    xtxt = ""
    Return
  End If
  ; Get root of document
  XML_Root = MSXML.documentElement
  Return XML_Root

#EndFunction

xtxt = FileGet("xml_test.xml")
XML_Root = Load_MSXMLData(xtxt)
loaded_txt = XML_Root.xml
Message("XML",loaded_txt)


 

td:
The .Net System.Xml namespace with WinBatch CLR hosting should be able to perform what the OP requires. The C# examples on the page indicated by the MSFT link below provide a good starting point for a WIL script.

https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmldocument?view=netframework-4.8.1


[edit] Jim's COM Automation suggestion is also worth checking out. It can do most/all of what is needed and is likely easier to understand unless you are already familiar with dotNet script in WinBatch. You can dump the progid "MSXML2.DOMDocument.6.0" into The WIL Typeviewer to get some idea of the available properties and methods.

stanl:
Here is some quickie PS code to parse the xml data OP provided with output attached. My thoughts were to quickly collect the properties, queue up any changes then just write back to the xml file with replace functions. Maybe a bit simplistic. Oh, and WB can easily call the PS code. I suspect as Jim suggested that MSXML and xpath could accomplish the same in pure WB.

--- Code: ---
#parse xml into bar-delimited text for properties
#change xml and txt output as needed
$file = "c:\temp\zombies.txt"
$data = "class|property|value" | out-file $file
[xml] $info = Get-Content -Path C:\temp\zombies.xml
$base = $info.entity_classes.entity_class
ForEach ($class in $base)
{
     $name = $class.name
     $props = $class.property
     ForEach ($prop in $props)
     {
        $data = $name + "|" +$prop.name + "|" + $prop.value
        $data | Out-File $file -Append
     }
}
Exit

--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version