Best approach to XML dialogues

My game needs a dialogue system and trough research I found that using a XML to format the dialogues is the best approach to create a “script” for the game. I made this XML:

<script>
	<dialogue>
		<id>1</id>
		<speaker>renata</speaker>
		<speech>blablablabla</speech>
		<duration>3</duration>
		<option_1>yes</option_1>
		<option_2>maybe</option_2>
		<option_3>no</option_3>
	</dialogue>
</script>

I know it’s not very good, but the person who is writing the script don’t know how to use XML, so I did a Google Sheet and after I will convert it to a CSV and XML.

And my dialogue “logic” will be:

Every NPC has an “dialogue range”, which will tell the game where the dialogue begins and ends, so I need to read the ID of the lines.

So I tried to parse the XML into a list, but i can’t get only a single element of the XML (like “id”)

var rows = XDocument.Load("script.xml")
                    .Root.Elements()
                    .Select(row => row.Value).ToList();

My question is:

Which structure is the best for me to parse the XML, so I can get the element ID of the lines instead of a unique string?

I highly recommand you to use another method to manage XML files. The .Net framework proposes a very simple way to do that using xmlserializer.

You just have to define a class (which does not inherit from MonoBehaviour since it’s just a data container)

Take a look at a function I made for a project. One is for serialization (save into an XML file), the other for deserialization (extract from file)

// ====================================================================================================
/// <summary>
/// Serializes the sculpture to store the data into an xml file.
/// </summary>
public void SerializeSculpture()
{		
	XmlSerializer serializer = new XmlSerializer( typeof( C_Sculpture ) );
	System.IO.StreamWriter streamWriter = System.IO.File.CreateText( pathToResources + "/data.xml" ) ;

	// scultureData is type of C_Sculpture    
	serializer.Serialize( streamWriter, sculptureData );

	streamWriter.Close() ;
	streamWriter.Dispose() ;
}

// ====================================================================================================
/// <summary>
/// Deserializes the sculpture if an xml file exists. 
/// </summary>
public void DeserializeSculpture()
{	
	System.IO.FileStream fileStream ;
	XmlReader reader ;
	XmlSerializer serializer = new XmlSerializer( typeof( C_Sculpture ) );

	// Check if file exists before opening a stream reader on it
	if( !System.IO.File.Exists( pathToResources + "/data.xml" ) )
	{
		fileStream = System.IO.File.Create( pathToResources + "/data.xml" ) ;
		fileStream.Close() ;
		fileStream.Dispose() ;
		SerializeSculpture() ;
	}
	else
	{
		// Open the data file and read it so as to fill the sculptureData structure
		fileStream = new System.IO.FileStream( pathToResources + "/data.xml", System.IO.FileMode.Open );
		reader = new XmlTextReader(fileStream) ;

		try
		{
			if( serializer.CanDeserialize( reader ) )
				sculptureData = serializer.Deserialize( reader ) as C_Sculpture;
		}
		finally
		{
			// Don't forget to close the readers and streams !
			reader.Close() ;
			fileStream.Close() ;
			fileStream.Dispose() ;
		}
	}
}

For your case, you can define the a C_Dialogue class as follow :

using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;

[XmlRoot("Dialogue")]
public class C_Dialogue
{	
	/* ======================================== *\
     *               ATTRIBUTES                 *
    \* ======================================== */
	
	/// <summary>
	/// Gets or sets the identifier.
	/// </summary>
	/// <value>The identifier.</value>
	[XmlAttribute]
	public int Id
	{
		get ;
		private set;
	}
	
	/// <summary>
	/// Gets or sets the speaker.
	/// </summary>
	/// <value>The speaker.</value>
	public string Speaker
	{
		get ;
		set ;
	}
		
	/// <summary>
	/// Gets or sets the speech.
	/// </summary>
	/// <value>The speech.</value>
	public string Speech
	{
		get ;
		set ;
	}
	
	/// <summary>
	/// Gets or sets the duration.
	/// </summary>
	/// <value>The long description.</value>
	public float Duration
	{
		get ;
		set ;
	}

	/// <summary>
	/// Gets or sets the options.
	/// </summary>
	/// <value>The options.</value>
	[XmlArray("Options")]
	[XmlArrayItem("Option")]
	public List<string> Options
	{
		get ;
		set ;
	}
	// ====================================================================================================
	/// <summary>
	/// Initializes a new instance of the C_Dialogue class.
	/// </summary>
	// YOU MUST DEFINE A CONSTRUCTOR WITHOUT ANY ARGUMENT
	public C_Dialogue( )
	{
		// Set default value here
	}
	
	// You can define other constructors if you want too
	public C_Dialogue( int id )
	{
		Id = id ;
	}
}