The mainline hierarchy. Contains bones and bone refs.
 public SpriterMainlineKey()
 {
     metaData = new List<SpriterMetaData>();
     hierarchy = new SpriterHierarchy();
     objects = new List<SpriterMainlineObjectBase>();
 }
        private void ReadBone(SpriterHierarchy hierarchy, XmlElement child)
        {
            var bone = new SpriterMainlineBone();
            hierarchy.bones.Add(bone);

            Vector2 position = Vector2.zero, scale = Vector2.zero;
            Color color = Color.white;

            foreach (XmlAttribute attribute in child.Attributes)
            {
                // id
                if (attribute.Name.Equals("id"))
                    bone.ID = int.Parse(attribute.Value);

                    // parent
                else if (attribute.Name.Equals("parent"))
                    bone.parent = int.Parse(attribute.Value);

                    // x, y
                else if (attribute.Name.Equals("x"))
                    position.x = float.Parse(attribute.Value);
                else if (attribute.Name.Equals("y"))
                    position.y = float.Parse(attribute.Value);

                    // angle
                else if (attribute.Name.Equals("angle"))
                    bone.angle = float.Parse(attribute.Value);

                    // scale_x, scale_y
                else if (attribute.Name.Equals("scale_x"))
                    scale.x = float.Parse(attribute.Value);
                else if (attribute.Name.Equals("scale_y"))
                    scale.y = float.Parse(attribute.Value);

                    // r, g, b, a
                else if (attribute.Name.Equals("r"))
                    color.r = float.Parse(attribute.Value);
                else if (attribute.Name.Equals("g"))
                    color.g = float.Parse(attribute.Value);
                else if (attribute.Name.Equals("b"))
                    color.b = float.Parse(attribute.Value);
                else if (attribute.Name.Equals("a"))
                    color.a = float.Parse(attribute.Value);
            }

            // Assign vector values
            bone.position = position;
            bone.color = color;

            foreach (XmlElement child2 in child)
            {
                // meta_data
                if (child2.Name.Equals("meta_data"))
                    ReadMetaData(child2, bone.metaData);
            }
        }
        void ReadHierarchy(XmlElement element, SpriterHierarchy hierarchy)
        {
            foreach(XmlElement child in element)
            {
                // bone
                if (child.Name.Equals("bone"))
                {
                    ReadBone(hierarchy, child);
                }

                // bone_ref
                else if (child.Name.Equals("bone_ref"))
                {
                    ReadBoneRef(hierarchy, child);
                }
            }
        }
        private static void ReadBoneRef(SpriterHierarchy hierarchy, XmlElement child)
        {
            var boneRef = new SpriterMainlineBoneRef();
            hierarchy.bones.Add(boneRef);

            foreach (XmlAttribute attribute in child.Attributes)
            {
                // id
                if (attribute.Name.Equals("id"))
                    boneRef.ID = int.Parse(attribute.Value);

                    // parent
                else if (attribute.Name.Equals("parent"))
                    boneRef.parent = int.Parse(attribute.Value);

                    // timeline
                else if (attribute.Name.Equals("timeline"))
                    boneRef.timeline = int.Parse(attribute.Value);

                    // key
                else if (attribute.Name.Equals("key"))
                    boneRef.key = int.Parse(attribute.Value);
            }
        }