Author Topic: Hold XML in a text variable  (Read 1285 times)

netkingcol

  • Newbie
  • *
  • Posts: 28
Hold XML in a text variable
« on: May 24, 2020, 02:37:39 AM »
Before I launch into a development project, is there any reason I can't hold an XML document, as a string, in a Text variable? I want to hold some structured information about scanned stars and planets in Elite Dangerous and don't need/want some heavy database to do it - holding the information in memory is fine for the duration of a session.

I would envisage manipulating the XML using an inline C# function which would input the XML variable and whatever parameters were needed for a given transaction e.g. record that an M5 class star has icy rings around bodies 2 and 3.

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4759
  • RTFM
Re: Hold XML in a text variable
« Reply #1 on: May 24, 2020, 10:18:22 AM »
VoiceAttack text variables use the string datatype, so as long as you get and set its value from your inline function, there is no functional difference.

However, if you use other actions within a command to get, and especially set the value of that variable, the formatting can be affected, as certain characters are interpreted as instruction indicators, E.G. square brackets, colons, semicolons, etc...

netkingcol

  • Newbie
  • *
  • Posts: 28
Re: Hold XML in a text variable
« Reply #2 on: May 29, 2020, 04:25:01 AM »
I am  :D

You are right about there being possible issues with some characters in the XML. Specifically, my commands would not work while the Text variable holding the XML included the XML directive itself: <?xml version='1.0'?>.

The behaviour was a little puzzling until I took the directive out; the commands would behave correctly when executed using the right-click in the 'Edit a Profile' window, but would not work when executed from a button. I don't need to know why, it's just something for others to be aware of.

Thanks for your help.

 

netkingcol

  • Newbie
  • *
  • Posts: 28
Re: Hold XML in a text variable
« Reply #3 on: May 29, 2020, 05:00:42 AM »
...and if anyone's interested, here's the inline function to update an XML document, based on the contents of a second XML document, both of which are held as Text variables.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

public class VAInline
{
   public void main()
   {
           string starData;
           string surveyData;

            try
            {
               
                starData =VA.GetText("StarsInSystem");
                surveyData = VA.GetText("xmlSurvey");

                XmlDocument stars = new XmlDocument();
                stars.LoadXml(starData);
               
                XmlDocument xmlSurvey = new XmlDocument();
                xmlSurvey.LoadXml(surveyData);

                if (stars != null)
                {
                    XmlNodeList ndlStars = stars.DocumentElement.SelectNodes("//Star");
                   
                    if (ndlStars != null)
                    {
                        if (ndlStars.Count > 0)
                        {
                            foreach (XmlNode nStar in ndlStars)
                            {
                                // get the class, subclass, and icy ring count
                                string starClass = nStar.Attributes.GetNamedItem("class").Value;
                                string starSubClass = nStar.Attributes.GetNamedItem("subclass").Value;
                                int icyRingCount = Convert.ToInt16(Convert.ToInt16(nStar.Attributes.GetNamedItem("icyrings").Value));

                                // find the class and subclass in the survey document
                                XmlNode surveyStar = xmlSurvey.SelectSingleNode("//Star[@class='"+starClass+"' and @subclass='"+starSubClass+"']");
                               
                                if (surveyStar != null)
                                {
                                    if (icyRingCount > 0)
                                    {
                                        XmlAttribute attIcyRings = (XmlAttribute)(surveyStar.Attributes.GetNamedItem("icyrings"));
                                        XmlAttribute attWithIcyRings = (XmlAttribute)(surveyStar.Attributes.GetNamedItem("withicyrings"));

                                        int surveyRingCount = (Convert.ToInt16(Convert.ToInt16(attIcyRings.Value))) + icyRingCount;
                                        int surveyWithRingsCount = (Convert.ToInt16(Convert.ToInt16(attWithIcyRings.Value))) + 1;

                                        attIcyRings.Value = surveyRingCount.ToString();
                                        attWithIcyRings.Value = surveyWithRingsCount.ToString();

                                    }
                                    else
                                    {
                                        XmlAttribute attWithoutIcyRings = (XmlAttribute)(surveyStar.Attributes.GetNamedItem("withouticyrings"));
                                        int surveyWithoutRingsCount = (Convert.ToInt16(Convert.ToInt16(surveyStar.Attributes.GetNamedItem("withouticyrings").Value))) + 1;

                                        attWithoutIcyRings.Value = surveyWithoutRingsCount.ToString();

                                    }
                                }
                            }
                        }
                    }
                     VA.SetText("updatedSurvey",xmlSurvey.OuterXml.ToString());
                     VA.SetInt("RC",0);
                }
            }
            catch (Exception ex)
            {
                VA.SetInt("RC",-1);
                VA.SetText("errSurvey",ex.Message);
            }

        }
 
   }