[C#] Need help with xml stuff...
-
Say for instance I have this as an xml:
<CWeaponInfoBlob> <SlotNavigateOrder> <Item> <WeaponSlots> <Item> <OrderNumber value="10" /> <Entry>SLOT_UNARMED</Entry> </Item> <Item> <OrderNumber value="20" /> <Entry>SLOT_KNIFE</Entry> </Item> <Item> <OrderNumber value="30" /> <Entry>SLOT_NIGHTSTICK</Entry> </Item> <Item> <OrderNumber value="40" /> <Entry>SLOT_HAMMER</Entry> </Item> <Item> <OrderNumber value="50" /> <Entry>SLOT_BAT</Entry> </Item> <Item> <OrderNumber value="60" /> <Entry>SLOT_CROWBAR</Entry> </Item> <Item> <OrderNumber value="70" /> <Entry>SLOT_GOLFCLUB</Entry> </Item> <Item> <OrderNumber value="90" /> <Entry>SLOT_PISTOL</Entry> </Item> <Item> <OrderNumber value="100" /> <Entry>SLOT_COMBATPISTOL</Entry> </Item> <Item> <OrderNumber value="110" /> <Entry>SLOT_PISTOL50</Entry> </Item> <Item> <OrderNumber value="120" /> <Entry>SLOT_APPISTOL</Entry> </Item> <Item> <OrderNumber value="130" /> <Entry>SLOT_STUNGUN</Entry> </Item> </WeaponSlots> </Item> </SlotNavigationOrder> </CWeaponInfoBlob>
How can I keep only elements that contain the word
STUN_GUN
for example, so that it looks like this:<CWeaponInfoBlob> <SlotNavigateOrder> <Item> <WeaponSlots> <Item> <OrderNumber value="130" /> <Entry>SLOT_STUNGUN</Entry> </Item> </WeaponSlots> </Item> </SlotNavigationOrder> </CWeaponInfoBlob>
NOTE: I have multiple xml nodes with different variations, but I'd like to remove any nodes that don't contain a certain word, while still keeping their parent and sibling nodes.
-
@sollaholla I think I did what you're looking for. It's a little tricky because you said the structure could be anything, so you'll need to specify some parameters at the top to adjust it for another XML file. You can turn this code into a function and have those parameters be passed into the function to modularize it:
using System.Xml; // Load your XML XmlDocument doc = new XmlDocument(); doc.Load("input.xml"); // XPath for the parent node of your list to filter String filterParent = "CWeaponInfoBlob/SlotNavigateOrder/Item/WeaponSlots"; // Node name that you're going to filter against String filterNodeName = "Entry"; // Node value that you're looking for String filterNodeValue = "STUNGUN"; // Get a reference to the parent node of the list XmlNode itemsParent = doc.SelectSingleNode(filterParent); // Clone the parent node and empty it out XmlNode filteredParent = itemsParent.Clone(); filteredParent.RemoveAll(); // Iterate over all the children in the parent node foreach (XmlElement item in itemsParent.ChildNodes) { // If the node name you're looking for exists and its text contains your filter value if (item[filterNodeName] != null && item[filterNodeName].InnerText.Contains(filterNodeValue)) { // Add it to the filtered parent filteredParent.AppendChild(item); } } // Get a reference to the parent of the parent node and empty it out XmlNode filteredInsertNode = itemsParent.ParentNode; filteredInsertNode.RemoveChild(itemsParent); // Insert your new filtered list filteredInsertNode.AppendChild(filteredParent); // Print out the XML, write to file, etc... Console.WriteLine(doc.OuterXml);
-
@rappo This is perfect!!!
Originally I was using Linq, and it was really messy, I had to specify so many parameters, but this works much better and seems much more modular. Thanks, dude!
-
@sollaholla Just in case you are looking for a general purpose way to save and load XML data without much ado, you could try this: https://www.gta5-mods.com/tools/xmlio