Reading XML data from website


#1

I am attempting to read the product page of a certain website, however I get an error on line 27, stating that goXML does not have a function named listChildren, along with all other p5 .xml functions. However, xml, a variable defined earlier in the code, works just fine. Is there something I’m missing here, because to me I should be able to access those functions.

Thanks.

var xml;
var json;

function preload() {
  xml = loadXML('https://undefeated.com/collections/new.atom');
  json = loadJSON('https://undefeated.com/collections/new.json');
}

function setup() {
  // put setup code here
  var allChildren = xml.listChildren();

  var products_raw = xml.getChildren('entry');
  var products = [];

  for (var i = 0; i < products_raw.length; i++) {
    var title = products_raw[i].getChild('title');
    var link = products_raw[i].getChild('link').attributes.href + '.xml';
    var tags = products_raw[i].getChildren('s:tag');
    console.log(link.type);
    products.push(new Product(title, link, tags));
  }

  var goXML = loadXML(products[0].link);
  console.log(goXML);
  console.log(goXML.type);
  var variants = goXML.listChildren();

}

function draw() {
  // put drawing code here
}

function Product(title, link, tags) {

  this.title = title;
  this.link = link;
  this.tags = tags;

}```

#2

Of course it works! B/c it’s in the right place, inside preload(), which fully loads assets before setup() starts: :star_struck:
https://p5js.org/reference/#/p5/preload

Well, the statement var goXML = loadXML(products[0].link); happens after preload() is long over. :slightly_frowning_face:

Easiest fix is simply moving it to preload() like the 1s already there. :bulb:

However, this particular asset loading depends on xml to be already 100% loaded! :sweat:

In such case, you may try to chain-load it right after xml is done. :chains:
In order to pull that out, pass a success callback as its 2nd parameter: :calling:

xml = loadXML('https://undefeated.com/collections/new.atom', loadProducts);

Notice the variable loadProducts as the 2nd argument of loadXML() there. :warning:

It’s supposed to be the function loadXML() calls back when the loading is 100% fully done. :100:

Now, move your whole products code inside that loadProducts() callback function, including both the loop and the 2nd loadXML(). :innocent:

All of that is gonna happen before setup() even starts! :smile_cat:


#3

Here’s a sketch which does something very similar:

  1. Online sketch: ThimbleProjects.org/gotoloop/96556/
  2. Source code: ThimbleProjects.org/gotoloop/96556/sketch.js

That sketch needs to load images whose links are inside a “.csv” file:
ThimbleProjects.org/gotoloop/96556/players.csv

So it 1st loads it within preload():

function preload() {
  loadTable(FILENAME, createPlayers);
}

Once the “.csv” file asset is complete, it calls back createPlayers():

function createPlayers(table) {
  players.length = 0, entries = table.getRowCount();

  for (const r of table.getRows())  players.push(
    new Player(loadImage(r.getString(0)), r.getString(1), r.getNum(2))
  );
}

Which in turn invokes loadImage() inside its loop. :cowboy_hat_face:

And when setup() finally starts, all resources are 100% ready to be used for the rest of the sketch! :partying_face:


#4

Wow thank you man, you have been really helpful!