Click here to Skip to main content
15,885,881 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello!

I know there is a lot of "Read and Write XML" samples out there, but I'm not sure why none worked... I think it is about my XML format or structure...

So... I want to read some specifics values from a XML, part of my XML is like:
<pre>
    <?xml version="1.0" encoding="utf-8"?>
<object hash="256A1FF9">
    <field name="disLibItemId" type="Id64">324266755348681119</field>
    <field name="Name" type="String">FC3/6P9</field>
    <object name="Entity">
        <field name="hidName" type="String">WeaponProperties:FC3/6P9</field>
        <field name="disEntityId" type="Int64">19832</field>
        <field name="text_hidEntityClass" type="String">CEntity</field>
            <object name="Components">
            <object name="CWeaponProperties">
                <field name="hidHasAliasName" type="Boolean">False</field>
            <object name="CommonProperties">
                <field name="sName" type="String">6P9</field>
            </object>
        </object> 
    </object>  
</object>


So lets assume i want to get the value "6P9", in my conception, code would look for
<Field Name "sName" type="String">6P9</field>
. and would get the value 6P9... but as long I tried coding and read some examples I noticed it isn't the way...


So, by only giving me a direction on this line I could understand what to do.

What I have tried:

I tried a lot of methods, loops, while, Xml functions, but I get lots of exceptions or wrong values...
Posted
Updated 11-Sep-21 15:38pm

Your XML isn't valid, which is why all the readers you found fail.
You can't have the same name for every part of your XML as nothing knows what the structure should be!
I tested it using an online validator: Validate XML files[^]

If I rewrite the names and reindent, it validates:
XML
<?xml version="1.0" encoding="utf-8"?>
<o1 hash="256A1FF9">
    <field name="disLibItemId" type="Id64">324266755348681119</field>
    <field name="Name" type="String">FC3/6P9</field>
    <o2 name="Entity">
        <field name="hidName" type="String">WeaponProperties:FC3/6P9</field>
        <field name="disEntityId" type="Int64">19832</field>
        <field name="text_hidEntityClass" type="String">CEntity</field>
        <o3 name="Components">
            <o4 name="CWeaponProperties">
                <field name="hidHasAliasName" type="Boolean">False</field>
                <o5 name="CommonProperties">
                    <field name="sName" type="String">6P9</field>
                </o5>
            </o4> 
        </o3>  
    </o2>
</o1>
And if I throw that into an online XML to C# converter: Xml2CSharp.com | Convert your XML Examples into XmlSerializer compatable C# Classes[^]
It gives me valid C# classes:
C#
 /* 
    Licensed under the Apache License, Version 2.0
    
    http://www.apache.org/licenses/LICENSE-2.0
    */
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{
	[XmlRoot(ElementName="field")]
	public class Field {
		[XmlAttribute(AttributeName="name")]
		public string Name { get; set; }
		[XmlAttribute(AttributeName="type")]
		public string Type { get; set; }
		[XmlText]
		public string Text { get; set; }
	}

	[XmlRoot(ElementName="o5")]
	public class O5 {
		[XmlElement(ElementName="field")]
		public Field Field { get; set; }
		[XmlAttribute(AttributeName="name")]
		public string Name { get; set; }
	}

	[XmlRoot(ElementName="o4")]
	public class O4 {
		[XmlElement(ElementName="field")]
		public Field Field { get; set; }
		[XmlElement(ElementName="o5")]
		public O5 O5 { get; set; }
		[XmlAttribute(AttributeName="name")]
		public string Name { get; set; }
	}

	[XmlRoot(ElementName="o3")]
	public class O3 {
		[XmlElement(ElementName="o4")]
		public O4 O4 { get; set; }
		[XmlAttribute(AttributeName="name")]
		public string Name { get; set; }
	}

	[XmlRoot(ElementName="o2")]
	public class O2 {
		[XmlElement(ElementName="field")]
		public List<Field> Field { get; set; }
		[XmlElement(ElementName="o3")]
		public O3 O3 { get; set; }
		[XmlAttribute(AttributeName="name")]
		public string Name { get; set; }
	}

	[XmlRoot(ElementName="o1")]
	public class O1 {
		[XmlElement(ElementName="field")]
		public List<Field> Field { get; set; }
		[XmlElement(ElementName="o2")]
		public O2 O2 { get; set; }
		[XmlAttribute(AttributeName="hash")]
		public string Hash { get; set; }
	}

}
That's probably not the structure you were expecting - and I have no idea what you did expect - but I'd start by going back to where you get the XML from and looking at what the heck it is doing - fix that, and your code may start to work!
 
Share this answer
 
So this explain why i spent 4 hours trying to code a a vast array of different XML Readers and nothing worked... I would post my codes here, but as i wrote, i tried about 6 or 7 methods before, so i gave up about XML editing and started to work in simple text reader...
My text here will be BIG, so sorry, i', trying to provide enough information...

This XML is a file From a Game, those files has about 1500 lines each, and game has about 200 different xml ones.
I normally edit with Notepad++ about 20 lines for file to make some changes on game, but it's very easy to make a mistake and crash game, my ideia is to make a vb.net editor, cappable to read specific lines and be able to edit it safely.

I found a workaround, if you took a look in line:
<field name="disEntityId" type="Int64">19832</field>

My code looks for specific string in a line, for example
"disEntityId"
, then read values betweeen
"">" and "</f"
...

But i had two problems here: I can't make a code to write new value and work properly, and also, there are some lines that has the very same name, and i need to edit, like:

<object name="RangeMultiplierHardcore">
              <object name="RangeMultiplierDifficulty">
                <object name="RangeMultiplier">
<!--THIS LINE--> <field name="fStartMultiplier" type="Float32">1</field>
                </object>
              </object>
     </object>
     <object name="RangeMultiplierCasual">
              <object name="RangeMultiplierDifficulty">
                <object name="RangeMultiplier">
<!--AND THIS LINE--> <field name="fStartMultiplier" type="Float32">2</field>
                </object>
              </object>
     </object>



As you can see, i need to edit the line where the following string is:
"fStartMultiplier"
, but this string is shown 2 times under different "Object Names" (RangeMultiplierCasual and Hardcore).



The full XML file is here: Microsoft OneDrive[^]

The code i worked to find the Word in line then show it's value is:

Private Sub Proccess()
Textbox1.Text = (StringBetweenChars(FindInLine(XmlFile, """disEntityId""")))
End Sub

Public Function StringBetweenChars(ByVal fullText) As String

        Dim start As String = Chr(34) + Chr(62)
        Dim ending As String = "</f"

        Dim x, j As Integer
        x = fullText.IndexOf(start) + 2
        j = fullText.IndexOf(ending)
        If (j <> -1) Then
            Return fullText.Substring(x, j - x)
        Else
            Return fullText.Substring(x, fullText.Length - x)
        End If
    End Function

    Private Function FindInLine(PathXml As String, Word As String) As String
        Using reader As New StreamReader(PathXml)
            While Not reader.EndOfStream
                Dim line As String = reader.ReadLine()
                If line.Contains(Word) Then
                    FindInLine = line
                    Exit While

                End If
            End While
        End Using
        If Word = "" Then Word = "Não Encontrado!"

    End Function


Thanks!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900