pythonxmllxmlxml-namespacescda

lxml xsi:schemaLocation namespace URI validation issue


I'm trying to use lxml.etree to reproduce the CDA example found in the CDA QuickStart Guide found here.

In particular, I'm running into issues with namespaces trying to recreate this element.

<ClinicalDocument xmlns="urn:hl7-org:v3" xmlns:mif="urn:hl7-org:v3/mif" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="urn:hl7-org:v3 CDA.xsd">

The code I'm using is as follows

root = etree.Element('ClinicalDocument',
                    nsmap={None: 'urn:hl7-org:v3',
                           'mif': 'urn:hl7-org:v3/mif',
                           'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
                           '{http://www.w3.org/2001/XMLSchema-instance}schemaLocation': 'urn:hl7-org:v3 CDA.xsd'})

The problem is with the schemaLocation entry in nsmap. lxml appears to be trying to validate the value and gives the error

ValueError: Invalid namespace URI u'urn:hl7-org:v3 CDA.xsd'

Am I specifying the schemaLocation value incorrectly? Is there a way to force lxml to accept any string value? Or is the value in the example simply intended to be a placeholder that I am supposed to replace with something else?


Solution

  • nsmap is a mapping of prefixes to namespace URIs. urn:hl7-org:v3 CDA.xsd is a valid value for the xsi:schemaLocationattribute, but it is not a valid namespace URI.

    The solution to a similar question, How to include the namespaces into a xml file using lxmf?, works here too. Use QName to create the xsi:schemaLocation attribute.

    from lxml import etree
    
    attr_qname = etree.QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation")
    
    root = etree.Element('ClinicalDocument',
                         {attr_qname: 'urn:hl7-org:v3 CDA.xsd'},
                         nsmap={None: 'urn:hl7-org:v3',
                                'mif': 'urn:hl7-org:v3/mif',
                                'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
                                })