What I want to do:
I am trying to generate an XSD file for an existing XML file.
I'm using the xsd.exe
tool (shipped with Visual Studio).
Some of the elements in the XML file are namespace-qualified. In some cases local names are the same, just as below:
<images>
<icons>
<icon url="http://www.icons.com/logo.png"/>
</icons>
<foo:icons>
<foo:foo_icon url="http://www.foo.org/pic.ico"/>
</foo:icons>
</images>
What I am getting:
Calling xsd.exe myfile.xml
gives me an error: Cannot add a column named 'icons': a nested table with the same name already belongs to this DataTable.
OK but that's what the namespace is for, isn't it? Resolving ambiguity like that. If there was no namespaces, I would just call the element foo_icons
instead of toying with prefixes.
What I tried:
I tried looking for a way to configure xsd.exe
so that it takes namespaces into consideration, but neither xsd /?
nor my google queries revealed any answer. The /n[amespace]:
parameter does not allow for specifying multiple namespaces.
I've read Working with Namespaces in XML Schema but I don't feel much wiser.
Do I have to create separate XSD files and embed them in eachother? It doesn't deal with using xsd.exe
for this purpose, either.
I'm really not too familiar with XSD, so I am probably misunderstanding some essential concepts about the whole process. I'd appreciate if someone could point me in the right direction.
Edit 1 - following Marc Gravell's suggestion:
I tried that, but I also had to rename a (prefixed) element which appeared in different sections of the XML (under different parent nodes) as xsd
would not allow that. I had to rename it to elementOne
, elementTwo
etc. I was going to rename it back manually. But the XSD I got does not work anyway.
The header is:
<xs:schema id="NewDataSet" targetNamespace="http://www.foo.com/bar" xmlns:mstns="http://www.foo.com/bar" xmlns="http://www.foo.com/bar" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified"
xmlns:app1="http://www.foo.com/bar/extensions"
xmlns:app2="http://www.w3.org/XML/1998/namespace">
And when I'm trying to validate a file with it, I'm getting an error:
Prefix 'app2' cannot be mapped to namespace name reserved for "xml" or "xmlns".
So, with what purpose has xsd.exe
generated it like that? How should it be fixed?
The way you're using xsd.exe to give you an XML Schema... it actually tries to come up with a DataSet; and that on .NET is very limited indeed.
I would use another option, available on .NET: to build a script using the .NET API documented here.
At least for your XML fragment, it'll work; I've tried it and it creates a valid XmlSchemaSet. Below is the test that I ran with the tool that I am using, which relies on the same API (with some additional bells and whistles that otherwise you'll have to do some minor fixes by hand).
Fixed XML (added the missing namespace declaration for foo prefix):
<images>
<icons>
<icon url="http://www.icons.com/logo.png"/>
</icons>
<foo:icons xmlns:foo="urn:tempuri-org:test">
<foo:foo_icon url="http://www.foo.org/pic.ico"/>
</foo:icons>
</images>
The top level schema (no target namespace, matches your images element):
<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema xmlns:foo="urn:tempuri-org:test" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import schemaLocation="XSDMultipleNamespaces1.xsd" namespace="urn:tempuri-org:test" />
<xsd:element name="images">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="icons">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="icon">
<xsd:complexType>
<xsd:attribute name="url" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element ref="foo:icons" />
</xsd:sequence>
</xsd:complexType>
The schema for the foo namespace:
<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema xmlns="urn:tempuri-org:test" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:tempuri-org:test" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="icons">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="foo_icon">
<xsd:complexType>
<xsd:attribute name="url" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
The generated XML Schema files are good to validate your XML.