Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Race Codes in CDA #2

Open
LRFalk01 opened this issue Jun 6, 2017 · 3 comments
Open

Multiple Race Codes in CDA #2

LRFalk01 opened this issue Jun 6, 2017 · 3 comments

Comments

@LRFalk01
Copy link

LRFalk01 commented Jun 6, 2017

I'm having a difficult time getting this to work. I've reviewed the following pages:
https://everest.codeplex.com/discussions/653908
http://te.marc-hi.ca/forums/default.aspx?g=posts&t=58

In my source XML I have the following:

<raceCode code="2106-3" displayName="White" codeSystem="2.16.840.1.113883.6.238" codeSystemName="Race &amp; Ethnicity - CDC"/>
<sdtc:raceCode code="2108-9" displayName="White European" codeSystem="2.16.840.1.113883.6.238" codeSystemName="Race &amp; Ethnicity - CDC"/>

Which fails to parse with the this error: System.Xml.XmlException: Can't parse 'raceCode' in namespace 'urn:hl7-org:sdtc'. The data does not appear to be an HL7v3 instance

This is my test that is blowing up:

        [TestMethod]
        public void ParseCcd()
        {
            var formatter = new XmlIts1Formatter();
            formatter.ValidateConformance = false;
            formatter.GraphAides.Add(new ClinicalDocumentDatatypeFormatter());
            formatter.RegisterXSITypeName("POCD_MT000040UV.Patient", typeof(MyPatientMultipleRaceCodes));
            formatter.Settings |= SettingsType.SuppressNullEnforcement | SettingsType.AlwaysCheckForOverrides;
            formatter.ValidateConformance = false;

            ClinicalDocument cda;
            using (var xr = new XmlStateReader(XmlReader.Create(@"C:\CDA_Tests\170.315_b1_toc_amb_ccd_r21_sample1_v8.xml")))
            {
                var result = formatter.Parse(xr, typeof(ClinicalDocument));
                cda = result.Structure as ClinicalDocument;
            }
        }

When I am rendering XML I have a different problem in that only one of the race codes is being assigned to the sdtc schema:

<sdtc:raceCode code="2106-3" codeSystem="2.16.840.1.113883.6.238" displayName="White" />
<raceCode code="2106-3" codeSystem="2.16.840.1.113883.6.238" displayName="White" />
<raceCode code="2108-9" codeSystem="2.16.840.1.113883.6.238" displayName="White European" />

Generated from this method:

        private MemoryStream RenderCda(ClinicalDocument cda)
        {
            XmlIts1Formatter fmtr = new XmlIts1Formatter();
            fmtr.RegisterXSITypeName("POCD_MT000040UV.Patient", typeof(MyPatientMultipleRaceCodes));
            fmtr.Settings |= SettingsType.SuppressNullEnforcement | SettingsType.AlwaysCheckForOverrides;
            fmtr.GraphAides.Add(new DatatypeFormatter());
            fmtr.ValidateConformance = false;

            // Prepare the output 
            var stream = new MemoryStream();
            XmlStateWriter xsw = new XmlStateWriter(XmlWriter.Create(stream, new XmlWriterSettings() { Indent = true }));
            xsw.WriteStartElement("ClinicalDocument", "urn:hl7-org:v3");
            xsw.WriteAttributeString("xmlns", "sdtc", null, "urn:hl7-org:sdtc");

            fmtr.Graph(xsw, cda);
            xsw.WriteEndElement();

            xsw.Flush();
            stream.Position = 0;

            return stream;
        }

I've been banging my head against this for quite awhile now. Any help would be welcomed.

@LRFalk01
Copy link
Author

LRFalk01 commented Jun 6, 2017

I was able to get the parse to work with a custom build of Everest. I added the and clause on line 12 (code is from XmlIts1Formatter.cs):


        public IFormatterParseResult Parse(XmlReader r, Type t)
        {
            if (!(r is XmlStateReader))
                r = new XmlStateReader(r);

            // Initial state
            if (r.ReadState == ReadState.Initial)
                while (r.NodeType != XmlNodeType.Element)
                    r.Read();

            // Detect if we can parse this...
            if (r.NamespaceURI != "urn:hl7-org:v3" && r.NamespaceURI != "urn:hl7-org:sdtc")
                throw new XmlException(string.Format("Can't parse '{0}' in namespace '{1}'. The data does not appear to be an HL7v3 instance", r.LocalName, r.NamespaceURI), null);

            var resultContext = new XmlIts1FormatterParseResult(ResultCode.Accepted, null);
            resultContext.Structure = ParseObject(r, t, null, resultContext);
            return resultContext;
        }

@LRFalk01
Copy link
Author

LRFalk01 commented Jun 6, 2017

I think the render issue is a bug where SET only applies the NamespaceUri from the property attribute on the first item in the collection:

[Property(Name = "raceCode", PropertyType = PropertyAttribute.AttributeAttributeType.NonStructural, NamespaceUri = "urn:hl7-org:sdtc")]
public new SET<CE<string>> RaceCode { get; set; }

@LRFalk01
Copy link
Author

LRFalk01 commented Jun 6, 2017

So, I was able to get this to work with a custom formatter:

        public class DlEverestFormatter : XmlIts1Formatter
        {
            protected override void GraphObject(XmlWriter s, IGraphable o, Type useType, IGraphable context, XmlIts1FormatterGraphResult resultContext)
            {
                var writer = (XmlStateWriter)s;
                if (writer.CurrentElement.Name == "raceCode" && useType.GetGenericTypeDefinition().FullName.Contains(".SET"))
                {
                    var raceCodes = (SET<CE<string>>)o;
                    var raceCodeCount = 0;
                    foreach (var raceCode in raceCodes)
                    {
                        if (raceCodeCount > 0)
                        {
                            s.WriteStartElement("raceCode", "urn:hl7-org:sdtc");
                        }

                        s.WriteAttributeString("code", raceCode.Code);
                        s.WriteAttributeString("codeSystem", raceCode.CodeSystem);
                        s.WriteAttributeString("displayName", raceCode.DisplayName);

                        raceCodeCount = raceCodeCount + 1;

                        if (raceCodeCount < raceCodes.Count)
                        {
                            s.WriteEndElement();
                        }
                    }
                    return;
                }

                base.GraphObject(s, o, useType, context, resultContext);
            }
        }

I also removed the NamespaceUri from my Patient class override RaceCode property. The override GraphObject takes care of setting the correct namespace for any raceCode past the first one. I will be doing the same for ethnicity which also has multiple in MU2015.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant