Powershell & XML: How to count specific elements for each node

11,833

Add a dot (.) at the beginning of your XPath to make it recognized as relative to current $info :

foreach ($info in $infos ){
    $info.SelectNodes("./CubeBlocks/MyObjectBuilder_CubeBlock[(@xsi:type='MyObjectBuilder_Drill')]/SubtypeName['SmallBlockDrill']" ,$ns).count
}
Share:
11,833
Tostito80
Author by

Tostito80

Updated on June 04, 2022

Comments

  • Tostito80
    Tostito80 almost 2 years

    Here is another one for my server for the PC Game - Space Engineers. The answer to this seems like it should be simple but it has me stuck as i can not find the right way to call this information.

    What I would like to do is get the count of how many times a specific element appears in each node. I have this partially working but not exactly what I want.

    Here is what I have so far:

    An excerpt from the XML (nodes folded except for target node)

    <MyObjectBuilder_Sector xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <Position>
      <SectorEvents>
      <AppVersion>
      <SectorObjects>
         <MyObjectBuilder_EntityBase xsi:type="MyObjectBuilder_CubeGrid">
            <CubeBlocks>
               <MyObjectBuilder_CubeBlock xsi:type="MyObjectBuilder_Reactor">
               <MyObjectBuilder_CubeBlock xsi:type="MyObjectBuilder_Thrust">
               <MyObjectBuilder_CubeBlock xsi:type="MyObjectBuilder_Drill">
               <MyObjectBuilder_CubeBlock xsi:type="MyObjectBuilder_Drill">
                  <SubtypeName>SmallBlockDrill</SubtypeName>
                  <EntityId>72280681079646079</EntityId>
                  <Min x="1" y="1" z="-7" />
                  <BlockOrientation Forward="Forward" Up="Left" />
                  <ColorMaskHSV x="0" y="-1" z="0" />
                  <Owner>144256542526969420</Owner>
                  <ShareMode>None</ShareMode>
                  <ShowOnHUD>false</ShowOnHUD>
                  <Enabled>false</Enabled>
                  <Inventory>
                    <Items />
                    <nextItemId>0</nextItemId>
                  </Inventory>
               </MyObjectBuilder_CubeBlock>
    

    and my powershell code that gives me back the number of cube blocks per

    <MyObjectBuilder_EntityBase xsi:type="MyObjectBuilder_CubeGrid">
    

    cube grid.

    $filePath = 'F:\DedicatedServer\DataDir\SE Survival 2\Saves\VPS RC 1\SANDBOX_0_0_0_.sbs'
    [xml]$myXML = Get-Content $filePath
    $ns = New-Object System.Xml.XmlNamespaceManager($myXML.NameTable)
    $ns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")
    
    $infos = $myXML.SelectNodes("//SectorObjects/MyObjectBuilder_EntityBase[(@xsi:type='MyObjectBuilder_CubeGrid')]" ,$ns)
    
    foreach ($info in $infos ){
    
            $info.CubeBlocks.MyObjectBuilder_CubeBlock.count 
    }
    

    So I am trying to get this to feed back the number of small drills per cube grid. seen here in the XML

    <MyObjectBuilder_CubeBlock xsi:type="MyObjectBuilder_Drill">
          <SubtypeName>SmallBlockDrill</SubtypeName>
    

    I feel Like this is close to solved but its returning the same number for every cube grid so that can not be correct.

    $info = $info.SelectNodes("//CubeBlocks/MyObjectBuilder_CubeBlock[(@xsi:type='MyObjectBuilder_Drill')]/SubtypeName['SmallBlockDrill']" ,$ns).InnerText
    $info.count
    

    Results below. I believe this is the total number of both large and small drills in the world just repeating for every grid it finds. feels close but i'm betting the subtype value selection is not working as I want it to.

    490
    490
    490
    490
    490
    490
    490
    490