static zfbool _ZFP_ZFXmlParseToSerializableData(ZF_OUT ZFSerializableData &serializableData,
                                                ZF_IN const ZFXmlItem &xmlElement,
                                                ZF_OUT_OPT zfstring *outErrorHintToAppend = zfnull,
                                                ZF_OUT_OPT ZFXmlItem *outErrorPos = zfnull)
{
    if(xmlElement.xmlIsNull())
    {
        ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("null xml element"));
        if(outErrorPos != zfnull)
        {
            *outErrorPos = xmlElement;
        }
        return zffalse;
    }
    if(xmlElement.xmlType() != ZFXmlType::e_XmlElement)
    {
        ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("param not type of xml element"));
        if(outErrorPos != zfnull)
        {
            *outErrorPos = xmlElement;
        }
        return zffalse;
    }

    if(xmlElement.xmlName() == zfnull)
    {
        ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("missing xml node name"));
        if(outErrorPos != zfnull)
        {
            *outErrorPos = xmlElement;
        }
        return zffalse;
    }
    serializableData.itemClassSet(xmlElement.xmlName());

    ZFXmlItem attribute = xmlElement.xmlAttributeFirst();
    while(!attribute.xmlIsNull())
    {
        if(attribute.xmlName() == zfnull)
        {
            ZFSerializableUtil::errorOccurred(outErrorHintToAppend, zfText("missing xml attribute name"));
            if(outErrorPos != zfnull)
            {
                *outErrorPos = attribute;
            }
            return zffalse;
        }
        if(zfscmpTheSame(attribute.xmlName(), ZFSerializableKeyword_refType))
        {
            serializableData.referenceRefTypeSet(attribute.xmlValue());
        }
        else if(zfscmpTheSame(attribute.xmlName(), ZFSerializableKeyword_refData))
        {
            serializableData.referenceRefDataSet(attribute.xmlValue());
        }
        else
        {
            serializableData.attributeSet(attribute.xmlName(), attribute.xmlValue());
        }

        attribute = attribute.xmlAttributeNext();
    }

    ZFXmlItem element = xmlElement.xmlChildElementFirst();
    while(!element.xmlIsNull())
    {
        ZFSerializableData childData;
        if(!_ZFP_ZFXmlParseToSerializableData(childData, element, outErrorHintToAppend, outErrorPos))
        {
            return zffalse;
        }
        serializableData.elementAdd(childData);
        element = element.xmlSiblingElementNext();
    }

    return zftrue;
}