You are here


XML Parser: Rendering the Item in Ruby

The first language to be used for XML parsing is Ruby. Ruby appears to have three main XML libraries: REXML, Hpricot, and libxml-ruby. As time allows, each will be tested.

Before starting the testing, several things need to be done. First, there needs to be a representation of the Item class in Ruby. From the pseudocode initially shown in the problem statement, I derive the Ruby representation of the Item class and its helper classes.

Since no limitations have been set for accessing or modifying the object's data, all fields are implemented with attr_accessor. Unfortunately, since attr_accessor does not have the ability to set default values, the variable initialization needs to be done in the constructor.

One notable difference between the pseudocode and the Ruby version is the casing. While the pseudocode uses "camel case" variable names as standard for Java, the Ruby version uses "underscore" variable names as per the conventions of the community. This creates small differences like critRating vs. crit_rating. There is an ongoing debate as to which is easier to read.

This represents the bare minimum thus far needed to implement the Item object. When discussing testing, other methods will be added to the Item class and helper classes.

XML Parser: Statement of Problem


World of Warcraft is an enormously popular MMORPG. Recently, Blizzard Entertainment announced that they had surpassed 11.5 million subscribers worldwide.

One of the many services offered by Blizzard Entertainment is the Armory which allows players to view their characters and others online. Items are also searchable through a recent update. All of the dynamic content (characters and items) are served as XML content which is then passed through XSL stylesheets to present the HTML content. This allows those who have the interest to query the Armory for the XML representation of an item or a character and then parse it locally.


Write an XML parser that processes an item's XML data and generates a data representation of that item.

Implementation Details

The XML data is stored in files with one paragraph per file.

The parser function should accept a single parameter, a filename, and return the expected object.

Elements that contain data as references not in the XML paragraphs can be left in the format present in the elements. The damageData element and the current attribute of the durability element may be ignored.

Implementations do not need to be object-oriented.


Four items have been randomly selected as test data:

  • 41660: Deadly Gladiator's Dragonhide Robes
  • 40503: Valorous Cryptstalker Tunic
  • 40526: Gown of the Spell-Weaver
  • 44006: Obsidian Greathelm

This data is by no means representative of what would need to be done to fully implement a parser for all equippable items in World of Warcraft. However, for the purpose of this exercise, it will suffice.

Based on the XML paragraphs, a generated item should have the following basic structure (expressed in "pseudo-Java"):

  1. class Item {
  2.     int id;                     /* id */
  3.     String name;                /* name */
  4.     String icon;                /* icon */
  5.     int quality;                /* overallQualityId */
  7.     int bonding;                /* bonding */
  8.     int classId;                /* classId */
  9.     int equipInventoryType;     /* equipData/inventoryType */
  10.     String equipSubclass;       /* equipData/subclassName */
  12.     int strength;               /* bonusStrength */
  13.     int agility;                /* bonusAgility */
  14.     int stamina;                /* bonusStamina */
  15.     int intellect;              /* bonusIntellect */
  16.     int spirit;                 /* bonusSpirit */
  17.     int armor;                  /* armor */
  18.     int addedArmor;             /* armor[armorBonus] */
  19.     String[] sockets;           /* one per socketData/socket */
  21.     int maxDurability;          /* durability[max] */
  22.     String[] allowedClasses;    /* one per allowableClasses/class */
  23.     int requiredLevel;          /* requiredLevel */
  24.     int attackPower;            /* bonusAttackPower */
  25.     int critRating;             /* bonusCritRating */
  26.     int expertiseRating;        /* bonusExpertiseRating */
  27.     int hasteRating;            /* bonusHasteRating */
  28.     int hitRating;              /* bonusHitRating */
  29.     int spellpower;             /* bonusSpellPower */
  30.     int resilience;             /* bonusResilience */
  32.     Spells[] spells;            /* one per spellData/spell */
  34.     ItemSet itemSet;            /* setData */
  35.     ItemSource source;          /* source */
  36. }
  38. class Spell {
  39.     int trigger;                /* trigger */
  40.     String desc;                /* desc */
  41. }
  43. class ItemSet {
  44.     String name;                /* name */
  45.     String[] items;             /* one per item */
  46.     Map<int, String> bonuses;   /* setBonus[ threshold ], setBonus[ desc ] */
  47. }
  50. class ItemSource {
  51.     String sourceType;          /* [value] */
  53.     /* These are only defined when sourceType == "sourceType.creatureDrop" */
  54.     int areaId;                 /* [areaId] */
  55.     String areaName;            /* [areaName] */
  56.     int creatureId;             /* [creatureId] */
  57.     String creatureName;        /* [creatureName] */
  58.     String difficulty;          /* [difficulty] */
  59.     int dropRate;               /* [dropRate] */
  60. }

If not specified by the XML data:

  • All integer values should return 0.
  • All strings should return null or the appropriate language equivalent thereof.
  • All arrays should be empty.

The returned data representations should match the above access terms unless language convention dictates otherwise. (For example, in a Java implementation, the methods would use the standard get... names, e.g. getStrength() in place of strength.)


  1. Clarified how the XML is stored. (2009/01/14)
  2. Removed object-oriented-specific terminology. (2009/01/14)
  3. Changed requirement on the value of unspecified arrays. (2009/01/14)
  4. Changed requirement on the durability element. (2009/01/25)
Subscribe to RSS - XML