#!/usr/bin/env python

# Uses the IATI Standard schema to create a list of 
# tests for IATI Data Quality.

from lxml import etree

organisations_schema = "iati-organisations-schema.xsd"
activities_schema = "iati-activities-schema.xsd"
common_schema = "iati-common.xsd"

NS = "{http://www.w3.org/2001/XMLSchema}"

activities_data = etree.parse(activities_schema)
common_data = etree.parse(common_schema)

datafiles = [activities_data, common_data]

elements = {}

def getAttributes(data):
    zattributes = {}
    try:
        attributes = data.find(NS+"complexType").findall(NS+"attribute")
        for attribute in attributes:
            zattributes[attribute.get('name')] = {}
    except Exception:
        pass
    return zattributes

def getSubElements(data):
    zsubelements = {}
    try:
        elements=data.find(NS+'complexType').find(NS+'choice').findall(NS+'element')
        #print etree.tostring(elements)
        for element in elements:
            try:
                element_name= element.get('name')
            except Exception:
                element_name=element.get('ref')
            zsubelements[element_name] = {}
            zsubelements[element_name]['attributes'] = getAttributes(element)
            zsubelements[element_name]['elements'] = getSubElements(element)
    except Exception:
        pass
    return zsubelements

def getElements(data):
    zelements = {}
    elements=data.findall(NS+"element")
    
    for element in elements:
        try:
            element_name= element.get('name')
        except Exception:
            element_name=element.get('ref')
        zelements[element_name] = {}
        zelements[element_name]['attributes'] = getAttributes(element)
        zelements[element_name]['elements'] = getSubElements(element)
    return zelements

def printAttributes(element, attributes, parent_element=None):
    for attribute in attributes:
        if attribute is not None:
            if parent_element is not None:
                parent = parent_element
            else:
                parent = element
            print parent + "/@" + attribute + " exists?"

def printElements(elements, parent_element=None):
    for element, element_data in elements.items():
        if ((element != "elements") and (element != "attributes")):
            if (parent_element is not None):
                print str(parent_element) + "/" + str(element) + " exists?"
            else:
                print element, "exists?"
            if parent_element is not None:
                parent = parent_element + "/" + element
            else:
                parent = element
            try:
                printAttributes(element, element_data['attributes'], parent)
            except Exception:
                pass
            try:
                printElements(element_data['elements'], parent_element=parent)
            except Exception:
                pass

def run():
    for datafile in datafiles:
        elements.update(getElements(datafile))

    printElements(elements)

run()

@@ -123,16 +123,26 @@
 rt etree
+%0Aimport re
 %0A%0Aorgani
@@ -470,72 +470,387 @@
  %7B%7D%0A
-%0Adef getAttributes(data):%0A    zattributes = %7B%7D%0A    try:%0A        
+attributes = %7B%7D%0A%0Adef cleanUpType(data):%0A    return re.sub(%22xsd:%22, %22%22, data)%0A%0Adef getAttributes(data):%0A    zattributes = %7B%7D%0A    attributes = data.findall(NS+%22attribute%22)%0A    for attribute in attributes:%0A        zattributes%5Battribute.get('name')%5D = cleanUpType(attribute.get('type'))%0A    return zattributes%0A%0Adef getElementAttributes(data):%0A    zattributes = %7B%7D%0A    try:%0A        the
 attr
@@ -927,32 +927,35 @@
 or attribute in 
+the
 attributes:%0A    
@@ -942,32 +942,53 @@
  theattributes:%0A
+            try:%0A    
             zatt
@@ -1016,26 +1016,173 @@
 ('name')%5D = 
-%7B%7D
+cleanUpType(attribute.get('type'))%0A            except Exception:%0A                zattributes%5Battribute.get('ref')%5D = attributes%5Battribute.get('ref')%5D
 %0A    except 
@@ -1375,48 +1375,8 @@
 t')%0A
-        #print etree.tostring(elements)%0A
     
@@ -1643,32 +1643,39 @@
 tributes'%5D = get
+Element
 Attributes(eleme
@@ -2144,24 +2144,31 @@
 utes'%5D = get
+Element
 Attributes(e
@@ -2339,32 +2339,48 @@
    for attribute
+, attribute_data
  in attributes:%0A
@@ -2369,32 +2369,40 @@
 ta in attributes
+.items()
 :%0A        if att
@@ -2611,16 +2611,94 @@
 exists?%22
+%0A            print parent + %22/@%22 + attribute + %22 is a %22 + attribute_data + %22?%22
 %0A%0Adef pr
@@ -3490,24 +3490,145 @@
 %0Adef run():%0A
+    for datafile in datafiles:%0A        attributes.update(getAttributes(datafile))%0A    attributes%5B'xml:lang'%5D = %22string%22%0A%0A
     for data

Add types