bool CDeviceXml::Deserialize(const TiXmlElement* pElement, CDevice& record)
{
  const char* name = pElement->Attribute(BUTTONMAP_XML_ATTR_DEVICE_NAME);
  if (!name)
  {
    esyslog("<%s> tag has no \"%s\" attribute", DEVICES_XML_ELEM_DEVICE, BUTTONMAP_XML_ATTR_DEVICE_NAME);
    return false;
  }
  record.SetName(name);

  const char* provider = pElement->Attribute(BUTTONMAP_XML_ATTR_DEVICE_PROVIDER);
  if (!provider)
  {
    esyslog("<%s> tag has no \"%s\" attribute", DEVICES_XML_ELEM_DEVICE, BUTTONMAP_XML_ATTR_DEVICE_PROVIDER);
    return false;
  }
  record.SetProvider(provider);

  const char* vid = pElement->Attribute(BUTTONMAP_XML_ATTR_DEVICE_VID);
  if (vid)
    record.SetVendorID(CStorageUtils::HexStringToInt(vid));

  const char* pid = pElement->Attribute(BUTTONMAP_XML_ATTR_DEVICE_PID);
  if (pid)
    record.SetProductID(CStorageUtils::HexStringToInt(pid));

  const char* buttonCount = pElement->Attribute(BUTTONMAP_XML_ATTR_DEVICE_BUTTONCOUNT);
  if (buttonCount)
    record.SetButtonCount(std::atoi(buttonCount));

  const char* hatCount = pElement->Attribute(BUTTONMAP_XML_ATTR_DEVICE_HATCOUNT);
  if (hatCount)
    record.SetHatCount(std::atoi(hatCount));

  const char* axisCount = pElement->Attribute(BUTTONMAP_XML_ATTR_DEVICE_AXISCOUNT);
  if (axisCount)
    record.SetAxisCount(std::atoi(axisCount));

  const char* index = pElement->Attribute(BUTTONMAP_XML_ATTR_DEVICE_INDEX);
  if (index)
    record.SetIndex(std::atoi(index));

  return true;
}