0

If I declare the xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://microsoft.com/wsdl/types/" >
    <xs:simpleType name="guid">
        <xs:annotation>
            <xs:documentation xml:lang="en">
                The representation of a GUID, generally the id of an element.
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:pattern value="([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})|(\{[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\})"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

Then I can use this in other xsds like:

<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:types="http://microsoft.com/wsdl/types/">

  <xs:import namespace="http://microsoft.com/wsdl/types/" />

  <!-- and at some point later -->
  <xs:attribute name="Id" type="types:guid" use="required" />

And when I run it all through xsd.exe I will end up with a property:

System.Guid Id { get; set;}

Which is great, but what I would dearly like to know is how does xsd.exe know to associate my type definition with System.Guid?

In fact what I really want to know is: is there some way of getting it to know about other types? Like is there a way to associate a string with System.Version, or two ints with System.Windows.Point?

(or is this just a special case feature that someone at Microsoft worked into the tool off the books?)

satnhak
  • 9,407
  • 5
  • 63
  • 81
  • Basic types have direct mappings. Complex types are defined in the XSD itself. Tools like svcutil will use the xsd file to generate these types. Mapping to *your* types requires decorating them with attributes, or passing the mappings to the serializer – Panagiotis Kanavos Feb 08 '17 at 10:11
  • That doesn't really answer either of my questions. XSD.exe generates types, but in this one special case it knows it can map to System.Guid after doing magic. I want to know how the magic trick is done. – satnhak Feb 08 '17 at 10:31
  • From the linked docs: `The World Wide Web Consortium (www.w3.org) document titled "XML Schema Part 2: Datatypes" specifies the simple data types that are allowed in an XML Schema definition language (XSD) schema. For many of these (for example, int and decimal), there is a corresponding data type in the .NET Framework. However, some XML data types do not have a corresponding data type in the .NET Framework (for example, the NMTOKEN data type). ...` – Panagiotis Kanavos Feb 08 '17 at 10:57
  • `In such cases, if you use the XML Schema Definition tool (XML Schema Definition Tool (Xsd.exe)) to generate classes from a schema, an appropriate attribute is applied to a member of type string, and its DataType property is set to the XML data type name. For example, if a schema contains an element named "MyToken" with the XML data type NMTOKEN, the generated class might contain a member as shown in the following example.` – Panagiotis Kanavos Feb 08 '17 at 10:58
  • Right, and GUID isn't one of those types. So I define some magic XSD and xsd.exe knows to convert that to System.Guid and the inbuilt serializer is down with that. That isn't in the documentation. – satnhak Feb 08 '17 at 11:00
  • That's just a paragraph in the Intro page. There are dozens of pages that explain how the serializer works, the attributes, namespaces, mappings etc. – Panagiotis Kanavos Feb 08 '17 at 11:01
  • Actually, I had to work quite a bit to customize the serializer to work with ebXML instead of SOAP. The `xsd.exe` and `svcutil.exe` do have some hard-coded tricks that aren't documented or consistent. In fact, the question [What is the correct way of using the Guid type in a XSD file?](http://stackoverflow.com/questions/687884/what-is-the-correct-way-of-using-the-guid-type-in-a-xsd-file) mentions exactly that - it's treated as a simple type even though it isn't documented, because it *is* part of the original simple types – Panagiotis Kanavos Feb 08 '17 at 11:06
  • In fact, if you want to serialize `System.Version` or `System.Windows.Point` it would be better to create DTOs with the appropriate attributes. Accessing and modifyint the mappings is complex and not very well documented. These classes contain members that can't be serialized, which means that you'd have to add mappings and exceptions for all of them. Far easier to create a DTO that contains only the desired properties and map to it eg with AutoMap – Panagiotis Kanavos Feb 08 '17 at 11:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/135168/discussion-between-briantyler-and-panagiotis-kanavos). – satnhak Feb 08 '17 at 11:17

0 Answers0