Handling namespaces in SQL XML Bulk Load can be a headache as there’s not really much documentation about it. However while laborious, it is basically following the normal XML Schema structure.
I’ll not go deep into the SQL XML Bulk Load syntax in this blog post, if you’re looking for that, I’ll advice you to read my SQL XML Bulk Load – basic XSD syntax or SQL XML Bulk Load – more XSD syntax blog posts before this one.
I’ve made this simplified example to illustrate. Suppose you have an XML file something akin to this:
<?xml version="1.0" encoding="utf-8"?>
<Catalogue xmlns:sdt="urn:oasis:names:specification:ubl:schema:xsd:SpecializedDatatypes-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Catalogue-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Catalogue-2 UBL-Catalogue-2.0.xsd">
<cbc:UBLVersionID>2.0</cbc:UBLVersionID>
<cac:ValidityPeriod>
<cbc:StartDate>2011-03-02</cbc:StartDate>
</cac:ValidityPeriod>
<cac:CatalogueLine>
<cbc:ID>11002</cbc:ID>
</cac:CatalogueLine>
<cac:CatalogueLine>
<cbc:ID>11003</cbc:ID>
</cac:CatalogueLine>
</Catalogue>
I have two custom namespaces, and a mixture of the elements within each namespace. This is simplified, but once the logic is known, it is just expanding it with more namespaces, and more mapping.
First we need to make the base XML schema/XSD file. A way to handle namespaces in the XSD file is to use import statements and split each namespace element in to its own separate file. And that technique works for SQL XML Bulk Load as well.
So we’ll make the base XSD like this
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xs:annotation>
<xs:appinfo>
<sql:relationship name="SomeName"
parent="Import"
parent-key="PK"
child="Import2"
child-key="FK" />
</xs:appinfo>
</xs:annotation>
<xs:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" schemaLocation="cbc.xsd" />
<xs:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" schemaLocation="cac.xsd" />
<xs:element name="Catalogue" sql:relation="Import">
<xs:complexType>
<xs:sequence>
<xs:element ref="cbc:UBLVersionID" />
<xs:element ref="cac:ValidityPeriod" />
<xs:element maxOccurs="unbounded" ref="cac:CatalogueLine" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Notice that each of the 3 elements simply has a reference to another element. So the XML tag cbc:UBLVersionID will in the XSD simply be element which ref=”cbc:UBLVersionID”, just as cac:ValidityPeriod element is also just a reference.
The key here however is that I’ve imported two namespaces with a schema location
<xs:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" schemaLocation="cbc.xsd" />
<xs:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" schemaLocation="cac.xsd" />
These lines will tell the base schema file where to look for the specific definitions for the namespaces.
Now, I can make a specific schema file for the cbc namespace and the cac namespace.
The cac one looks like
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
attributeFormDefault="unqualified" elementFormDefault="qualified"
targetNamespace="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" schemaLocation="cbc.xsd" />
<xs:element name="ValidityPeriod" sql:is-constant="1" >
<xs:complexType>
<xs:sequence>
<xs:element ref="cbc:StartDate" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CatalogueLine" sql:relationship="SomeName" sql:relation="Import2">
<xs:complexType>
<xs:sequence>
<xs:element ref="cbc:ID" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Here the same principle of using import statement to map a namespace
<xs:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" schemaLocation="cbc.xsd" />
is used similar to the base file.
The cac file is used to define the contents of all cac namespace elements (the naming of the file is irrelevant, I simply named them this way to help myself keeping track). And where needed in this cac file, a reference is made to an element in the cbc file (in this case cbc:StartDate and cbc:ID).
The cbc file will then qualify all cbc elements
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sql="urn:schemas-microsoft-com:mapping-schema"
>
<xs:element name="UBLVersionID" type="xs:decimal" sql:field="VersionID" />
<xs:element name="StartDate" type="xs:date" sql:field="DateX" />
<xs:element name="ID" type="xs:unsignedShort" sql:field="LineID" />
</xs:schema>
As can be seen, the sql:field, sql:relationship and sql:relation are all used across all 3 files.
In the base file, I’ve defined a relationship, and I’m using the relationship in the cac file around a cbc element.
Running this through a SQL XML Bulk Load, and I get my data imported into two tables like this

This was just a simplified example, but I hope it helps to show how the syntax is build up in a XSD and then spice it up with some SQL mapping.
For more insight into SQL XML Bulk Load and the syntax, you can check out my other posts on the subject.
Recent Comments