Boninseg
Boninseg

Reputation: 71

Select random node and add to label

i'm new to c# and trying to make a little randomizer. I want to select a random node where mystatus = 1 and show series_title and series_image in label.

Xml :

<?xml version="1.0" encoding="UTF-8"?>
<myanimelist>
 <myinfo>
  <user_id>5144371</user_id>
  <user_name>berefin</user_name>
  <user_watching>116</user_watching>
  <user_completed>100</user_completed>
  <user_onhold>3</user_onhold>
  <user_dropped>0</user_dropped>
  <user_plantowatch>52</user_plantowatch>
  <user_days_spent_watching>18.65</user_days_spent_watching>
</myinfo>
<anime>
  <series_title>Cowboy Bebop</series_title>
  <series_image>https://myanimelist.cdn- dena.com/images/anime/4/19644.jpg</series_image>
  <my_status>1</my_status>
</anime>
<anime>
  <series_title>Naruto</series_title>
  <series_image>https://myanimelist.cdn-dena.com/images/anime/13/17405.jpg</series_image>
  <my_status>1</my_status>
</anime>
<anime>
  <series_title>One Piece</series_title>      
  <series_image>https://myanimelist.cdn-dena.com/images/anime/6/73245.jpg</series_image>
  <my_status>2</my_status>
 </anime>

The Code so far :

private void btnRandom_MouseClick(object sender, MouseEventArgs e)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load("https://myanimelist.net/malappinfo.php?u=berefin&status=all&type=anime");

        XmlNodeList list = doc.SelectNodes("/myanimelist/anime");
        //string content = doc.InnerXml;

        foreach (XmlNode node in list)
        {
            // Not sure what to do here
            Random random = new Random();

            string my_status = node["my_status"].InnerText;


            if (my_status == "1")
            {
                string series_title = node["series_title"].InnerText;
                string series_image = node["series_image"].InnerText;


            }
        }

    }

How can i use random with xml node ?

Upvotes: 1

Views: 251

Answers (3)

AndrewR
AndrewR

Reputation: 168

Maybe not for beginners, but this works:

Your start:

XmlDocument doc = new XmlDocument();     
doc.Load("https://myanimelist.net/malappinfo.php?u=berefin&status=all&type=anime");
XmlNodeList list = doc.SelectNodes("/myanimelist/anime");

Create list with correct my_status:

var okList = list.Cast<XmlNode>().Where(xn => xn["my_status"].InnerText == "1");

Get a random number from 0 up to number of items in OkList:

var numOk = okList.Count( );
Random random = new Random();     
var numChosen = random.Next(numOk);

Get node at this position:

var node = okList.Skip(numChosen).First();

Get values from this node:

string series_title = node["series_title"].InnerText;
string series_image = node["series_image"].InnerText;

Upvotes: 1

Tatranskymedved
Tatranskymedved

Reputation: 4381

There exists 2 approaches, I will describe the one I like more. The other one would work the way that You will get numbers of elements that fit and then during reading You would just find the one with the number You've get from Random.

Like:

Random r = new Random();

//some code to get counted elements

int myOpt = r.Next( CountOfElements );

// some code to run through elemenets
if (myOpt == iterator)
{
    //get the details about Anime
}

Fill (materialize) into an array(list) and then randomly pick one

This one is ideal, if You want to do some work with the array later on, e.g. modify it or do any work. The best is to created class with the definition of Your objects, create array of this objects and then fill it up. Last thin is to find random entity from the array.

Class definition:

public class Anime
{
    public string series_title { get; set; }
    public string series_image { get; set; }
    public int my_status { get; set; }
}

Filling the list:

private void btnRandom_MouseClick(object sender, MouseEventArgs e)
{
    XmlDocument doc = new XmlDocument();
    doc.Load("https://myanimelist.net/malappinfo.php?u=berefin&status=all&type=anime");
    XmlNodeList list = doc.SelectNodes("/myanimelist/anime");
    var arr = new List<Anime>();

    foreach (XmlNode node in list)
    {
        arr.Add(new Anime()
        {
            series_title = node["series_title"].InnerText;
            series_image = node["series_image"].InnerText;
            my_status = Convert.ToInt32(node["my_status"].InnerText);
        } 
    }

    //here is all Your animes in list -> arr
}

In the end You can randomly pick one:

public Anime PickRandom(List<Anime> list)
{
    Random random = new Random();

    return list[random.Next(list.Count)];
}

Upvotes: 1

libertyernie
libertyernie

Reputation: 2686

First you'll want to make a new list of just the nodes whose my_status is 1. You can use your foreach loop to populate this list.

Then you'll want to get the size of this new list - in your case it should be 2. Then you can use:

int index = random.Next(0, size_of_new_list);
XmlNode node = size_of_new_list[index];

Upvotes: 1

Related Questions