Using xsd.exe1 to create C# classes for an XML Schema Document (XSD) is usually relatively straightforward, but I ran into a few snags when working with the ASTM’s CCR schema. I’m not sure if the problem is with the .NET Framework or the CCR schema. What follows is a detailed explanation of how I put together a useful C# class to create, modify, and save CCR files.
The CCR XML Schema Document (XSD) is available at ASTM for $67: Adjunct to E2369 Continuity of Care Record (CCR)
I renamed my XSD to CCR.xsd
The “maxOccurs” attribute for these two elements causes xsd.exe to create multi-dimensional arrays (e.g., public IndicationType[][] Indications;
). Simply delete the “maxOccurs” attribute as follows:
Find (occurs 3x in the XSD)
<xs:element ref="Indications" minOccurs="0" maxOccurs="unbounded"/>
Replace
<xs:element ref="Indications" minOccurs="0"/>
Find (occurs 1x in the XSD)
<xs:element ref="Directions" minOccurs="0" maxOccurs="unbounded"/>
Replace
<xs:element ref="Directions" minOccurs="0"/>
name
attributes to ref
for all IDs
elementsInstead of creating a new IDs
element each time, we just want to reference the root-level IDs
element. The type
attribute is not required when using ref
, so we can remove that as well:
Find (occurs 4x in the XSD)
<xs:element name="IDs" type="IDType" minOccurs="0"
Replace
<xs:element ref="IDs" minOccurs="0"
IDs
elementsSome elements inherit from CCRCodedDataObjectType
. Delete or comment out the redundant IDs
references in these elements:
We are now ready to convert our modified XSD file into a .NET class:
xsd.exe CCR.xsd /classes /namespace:CCR /language:CS
xsd.exe takes an XSD file and creates .NET code files.
/classes
tells xsd.exe to create classes./namespace:CCR
tells xsd.exe to use “CCR” as the namespace for the generated code./language:CS
tells xsd.exe to generate code in the CSharp languageThe following (abbreviated) command is equivalent:
xsd CCR.xsd /c /n:CCR
You should now have two files:
The simple arrays generated by xsd.exe lack helpful methods like Add()
. A type-specific List
would be much more useful:
// Bad
public ContinuityOfCareRecordPatient[] Patient;
// Good
public List<ContinuityOfCareRecordPatient> Patient;
So in the CCR.cs file, do a Find/Replace (with Regular Expressions turned on):
Regex Find2 (Occurs 252x in the XSD)
public {[^\[]+}\[\] {[^;]+};
Replace
public List<\1> \2;
You’ll also need to add using System.Collections.Generic;
to the top of your CCR.cs file.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using CCR;
namespace CCRTest
{
class Program
{
static void Main(string[] args)
{
try
{
ContinuityOfCareRecord ccr = Deserialize<ContinuityOfCareRecord>(@"C:\sampleCCR.xml");
System.Console.WriteLine(ccr.CCRDocumentObjectID);
foreach (ActorType at in ccr.Actors)
{
System.Console.WriteLine(" " + at.ActorObjectID);
}
}
catch (Exception ex)
{
while (ex != null)
{
System.Console.WriteLine(ex.ToString());
ex = ex.InnerException;
}
}
System.Console.ReadLine();
}
public static void Serialize<T>(T value, string pathName)
{
using (TextWriter writer = new StreamWriter(pathName))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, value);
}
}
public static T Deserialize<T>(string pathName)
{
using (TextReader reader = new StreamReader(pathName))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(reader);
}
}
}
}
*[CCR]: Continuity of Care Record *[XSD]: XML Schema Document *[ASTM]: American Society for Testing and Materials
If you don’t have xsd.exe (it doesn’t come with Visual Studio Express), you can download a copy from the Mono Project. The code generated by Mono’s xsd.exe works fine with Microsoft’s Visual Studio Express. ↩
This article uses the VS.NET Regex syntax. Notepad++ uses the following (functionally equivalent) syntax:
public ([^\[]+)\[\] ([^;]+);
↩