First cut at transforms.

13 views
Skip to first unread message

Michael Martin

unread,
Apr 4, 2013, 12:06:11 PM4/4/13
to 'vrrs@googlegroups.com' (vrrs@googlegroups.com)

OK, OK, I KNOW my HTML design stinks!  I’m more concerned at this point that I understand how to gather up all the content. 

 

Here is yet another sample document and its HTML transform.  (the content of the document is also stupid.  Before we use this stuff in marketing, I need you all to write more persuasive sample content following this pattern.

 

Two issues presented in the CDA and HTML transforms that I don’t think I’ve presented to the group.

 

1.       Credentials doesn’t have a clean mapping to CDA that I know of.  I modeled that as simply more name suffixes.

2.       CDA dropped effectiveTime from Order when converting from the true RIM.  I have no idea why.  I posted a question to the CDA list and got a response from Leora herself.  She doesn’t know why it was dropped.  I did not jump through the hoops in my transform schema to put that in the vrrs namespace, so technically any Order with an effectiveTime will make invalid CDA.  Do we care?  If and when someone tells me how to map it, I’ll do so.

 

So, homework for the group:

1.       Make me an example of better layout for the HTML content.  If you can stick to the data that are there and just tweak the HTML elements around it, it will be reasonably simple to hack that into the transform.

2.       Make up some realistic scenario documents in XML by following the pattern in the examples so far.

 

Michael K. Martin, DVM, MPH, DACVPM

Clemson Livestock Poultry Health

PO Box 102406

Columbia, SC 29224-2406

email: mma...@clemson.edu

personal email: michael.mar...@gmail.com

phone: (803) 788-2260 

direct line: (803) 726-7808

work cell: (803)312-1439

personal cell: (803)348-1879

fax: (803) 736-8058

 

"Most of our contemporary troubles arise from that odd
willingness to allow the machine to be master instead of slave."

JOHN BAKELESS

MIT Technology Review, 1931

 

HTMLVersion.html
VRRS_Schema_0.4.xsd
VRRSExample4.xml

Aerik Sylvan

unread,
Apr 4, 2013, 12:28:56 PM4/4/13
to vr...@googlegroups.com
Michael,

Are you hand coding the xsd?  That's pretty clean.  I've mostly relied on auto-generated xsds and they don't come out as nice.  I'm reasonably competent with simple XSLs however; can you send the transform you used to generate the html and I'll play with it as time permits?

BTW, do we have any central store of VRRS information beside the Google Group?  I've been kind of searching through the conversations and have gleaned some stuff, but haven't found any pointers to any other sources of info - and I'm trying to do my own research before I start asking dumb questions.

Thanks,
Aerik


--
You received this message because you are subscribed to the Google Groups "Veterinary Radiology Report Integration Work Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vrrs+uns...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Michael Martin

unread,
Apr 4, 2013, 12:53:20 PM4/4/13
to vr...@googlegroups.com

Yes, the schema is pretty much hand coded.  I’ve had similar experience with generated XSD.  I sometimes use it for reference. But it is easier to start over than to edit what the machine wrote. (My department chairman when I used to teach programming told me that I didn’t care if my code worked as long as it was pretty.  He was more than a little right.  It is just so much easier to debug well—in my own opinion—laid out code.)  I use oXygen editor which does a lot of code-completion for me.  But I mostly figure out how I want to lay things out.  Since we went back to trying to be a  “Green CDA” I keep the original HL7 CDA schemas open for reference as to sequence order, etc.

 

The transform is partly plagiarized (with attribution).  I started with an example CDA to HTML transform and have hacked it to death.  The result is totally inconsistent style, lots of dead code, etc.  But you are welcome to see what you can do with it.  That may be pushing the limits of the new HL7 IP but I think this is derivative enough that I’m not just passing on copyrighted info.

 

The project has a Google Sites page.  https://sites.google.com/site/vetradiologyreportstandards/  That has requirements documents, implementation guide drafts, etc.  We don’t keep it as up to date as we probably should.

 

Mike

VRRS-HTML.xsl

Evgeniy Gladyshev

unread,
Apr 4, 2013, 1:48:40 PM4/4/13
to vr...@googlegroups.com
Mike,

It looks great!
I think it simplifies things a lot comparing to the previous idea of having linked report editions. Am I correct that we can now get away with one report (identified by the same UID) which content may change over time (new addendum or some other section), or is it still recommended by VRSS to use separate UID's? 
Regarding the use of <title>/<paragraph>. I guess these could be used for semantical and/or presentation purposes? So about presentation, is it allowed to embed <![CDATA[...]]  with actual HTML or there is a better way to *partially force* a presentation format for some content?
If we decide to develop a REST-full API to generate VRRS reports by remedy for testing, is there anybody working on the consumer side of things? Perhaps some practice management client?

Thanks,
-Eugene


On Thu, Apr 4, 2013 at 9:06 AM, Michael Martin <mma...@clemson.edu> wrote:

--

Dennis Ballance

unread,
Apr 4, 2013, 3:51:41 PM4/4/13
to vr...@googlegroups.com

Eugene,

 

Yes, I can send you contact info for one group that is consuming VRRS documents that would be delighted to have a partner to test against.

 

Regarding linked documents, I believe CDA intends that once a document has been constructed with a UID, then that document is immutable. Hence, a version of the document with additional addenda would want to have a different UID (and refer to the earlier edition as its parent document). Note that the new version could have multiple addenda, each with its own author.

 

This issue of addenda has been a sticky one for multiple potential users. The challenge is that the “addendum” section of a standard report has been converted to become a communication channel. Ideally, the telemedicine provider and the requestor would be able to engage in a sideband discussion that could include requests, questions, and responses, while the report itself contains the actual medical data, and, if desired, a transcript of the sideband discussion.  If this model were used, then a new version of the report wouldn’t have to be delivered each time the specialist replied to a question.

 

That said, it is NOT the intention of VRRS to force changes to existing workflows. So, if as a provider you prefer to deliver each comment as an addendum to the report, that can be done too.  You could also deliver the same UID with each version of the document, though there is a risk that doing so might confuse some consumers if they try to build a CDA-compatible consumption engine.  One benefit of changing the UID each time is that it becomes really easy for the consumer to verify that they have the latest version of the report.

 

Mike, did I get this right?

 

--Dennis

 

From: vr...@googlegroups.com [mailto:vr...@googlegroups.com] On Behalf Of Evgeniy Gladyshev
Sent: Thursday, April 04, 2013 10:49 AM
To: vr...@googlegroups.com
Subject: Re: [VRRS] First cut at transforms.

 

Mike,

Michael Martin

unread,
Apr 4, 2013, 4:02:54 PM4/4/13
to vr...@googlegroups.com

CDA includes a number of elements designed to be a compromise between HTML (designed for presentation) and XML (designed for consistent data representation).  In setting up the VRRS schema we picked a subset of those elements.

 

The real problem with the report writer inserting lots of formatting is that it violates the design strategy that allows the rendering application to present the data in a format consistent with its GUI.  In my little HTML transform, I turned paragraphs into unsigned list items as a cheap and easy way to lay them out.  Another transform might turn them into Rich Text paragraphs.  Or something completely different.

 

If you had a consumer that really didn’t want to deal with doing their own formatting, there is no one stopping you from doing the transform on the producer end and offering them fully formatted output.  But that more or less gets us back to where we started. 

 

Mike

 

From: vr...@googlegroups.com [mailto:vr...@googlegroups.com] On Behalf Of Evgeniy Gladyshev
Sent: Thursday, April 04, 2013 1:49 PM
To: vr...@googlegroups.com
Subject: Re: [VRRS] First cut at transforms.

 

Mike,

Evgeniy Gladyshev

unread,
Apr 4, 2013, 4:58:09 PM4/4/13
to vr...@googlegroups.com
Dennis, Mike thanks a lot for the clarifications. 

I agree with your point about UID. It should not be a problem implementing it the way you described at all.

I completely agree adding presentation elements defeats the whole purpose, and at least for our use cases, <title> and <paragraph> would be adequate for now. However, I would not bet that we won't need some support for MIME types in the near feature. As far as I understand there is a huge movement toward adopting MIME types as portable presentation vehicle. For example in pure REST theory, all presentation is supposed to be handled by MIME types. Rendering clients needs to know is how to present various MIME types only. One can imagine that the <title> element could have a mime type attribute of "text/plain" or "text/html" so that the consumer immediately know what to do with that or it could be "image/jpeg". Consequently, data elements may have alternative mime types (ideally in priority order) for the rendering engine to pick from. Paragraph could have an image as the main content and text as an alternative. The client could use the text mime for search, presentation, etc.. I am not sure if I am going to far here but I can already see that we could make use of it. It seems very scale-able in terms adding a bunch of new features w/o rewriting the whole standard. Also, I believe that I'd simplify the development of rendering clients, make the integration easier, and significantly improve portability. I was wondering if you thought about this stuff.

Thanks,
-Eugene


Michael Martin

unread,
Apr 5, 2013, 8:25:58 AM4/5/13
to vr...@googlegroups.com

First, on the UID question:  Last night I was thinking that, if it would help, we could add an element to the VRRS Green version for something like “RootUID” that would point to the initial published report in every case.  You can find the same thing now by following the ParentID values until you hit a null.  If that would help with keeping the whole chain together, it wouldn’t break anything.  It just wouldn’t translate to true CDA except by walking the linked list backwards.

 

On embedded MIME content:  I believe we need to keep the distinction between report and the images it references clear.  There are plenty of ways to reference external binary sources.  The need to embed what HL7 calls “encapsulated data” (ED) in the report itself would apply to things like if you needed to draw a picture of a lesion to explain some point.  If you need to simply refer to a specific part of a specific image, I think that can be done by reference (right Dennis?)

 

My only fear about adding support for embedded binary is that the complexity, while helping the 1% that need it, will frighten off the 99% who don’t.

 

I’ve included a little bit of the full CDA schema below.  What we have done in VRRS is simplify out as much of this as we believe was not really needed.  The Green2CDA.xsl transform puts back all the complicated bits in a fixed way to make a document instance that complies with the full CDA schema. 

 

We could, now that the IP rules have changed, just put out the full schema with the extension for animal patients.  But I doubt very many programmers want to deal with that.  So, there is going to be an ongoing tension between keeping our “green version” simple enough for real-world use and complete enough to be useful when used.

 

Mike

 

   <xs:complexType name="StrucDoc.Text" mixed="true">
     
<xs:choice minOccurs="0" maxOccurs="unbounded">
        
<xs:element name="content" type="StrucDoc.Content"/>
        
<xs:element name="linkHtml" type="StrucDoc.LinkHtml"/>
        
<xs:element name="sub" type="StrucDoc.Sub"/>
        
<xs:element name="sup" type="StrucDoc.Sup"/>
        
<xs:element name="br" type="StrucDoc.Br"/>
        
<xs:element name="footnote" type="StrucDoc.Footnote"/>
        
<xs:element name="footnoteRef" type="StrucDoc.FootnoteRef"/>
        
<xs:element name="renderMultiMedia" type="StrucDoc.RenderMultiMedia"/>
        
<xs:element name="paragraph" type="StrucDoc.Paragraph"/>
        
<xs:element name="list" type="StrucDoc.List"/>
        
<xs:element name="table" type="StrucDoc.Table"/>
     
</xs:choice>
     
<xs:attribute name="ID" type="xs:ID"/>
     
<xs:attribute name="language" type="xs:NMTOKEN"/>
     
<xs:attribute name="styleCode" type="xs:NMTOKENS"/>
     
<xs:attribute name="mediaType" type="xs:string" fixed="text/x-hl7-text+xml"/>
  
</xs:complexType>

 

The full version of “Text” including all the detail we didn’t implement.  Notice renderMultiMedia

 

   <xs:complexType name="StrucDoc.RenderMultiMedia">
     
<xs:sequence>
        
<xs:element name="caption" type="StrucDoc.Caption" minOccurs="0"/>
      
</xs:sequence>
     
<xs:attribute name="referencedObject" type="xs:IDREFS" use="required"/>
     
<xs:attribute name="ID" type="xs:ID"/>
     
<xs:attribute name="language" type="xs:NMTOKEN"/>
     
<xs:attribute name="styleCode" type="xs:NMTOKENS"/>
  
</xs:complexType>

 

The xs:IDREFS points to one or more Entry elements in the StructuredBody below the Text

 

            <xs:complexType name="POCD_MT000040.Entry">
                       
<xs:sequence>
                                   
<xs:element name="realmCode" type="CS" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="typeId" type="POCD_MT000040.InfrastructureRoot.typeId" minOccurs="0"/>
                                   
<xs:element name="templateId" type="II" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:choice>
                                               
<xs:element name="act" type="POCD_MT000040.Act"/>
                                               
<xs:element name="encounter" type="POCD_MT000040.Encounter"/>
                                               
<xs:element name="observation" type="POCD_MT000040.Observation"/>
                                               
<xs:element name="observationMedia" type="POCD_MT000040.ObservationMedia"/>
                                               
<xs:element name="organizer" type="POCD_MT000040.Organizer"/>
                                               
<xs:element name="procedure" type="POCD_MT000040.Procedure"/>
                                               
<xs:element name="regionOfInterest" type="POCD_MT000040.RegionOfInterest"/>
                                               
<xs:element name="substanceAdministration" type="POCD_MT000040.SubstanceAdministration"/>
                                               
<xs:element name="supply" type="POCD_MT000040.Supply"/>
                                   
</xs:choice>
                       
</xs:sequence>
                       
<xs:attribute name="nullFlavor" type="NullFlavor" use="optional"/>
                       
<xs:attribute name="typeCode" type="x_ActRelationshipEntry" use="optional" default="COMP"/>
                       
<xs:attribute name="contextConductionInd" type="bl" use="optional" fixed="true"/>
           
</xs:complexType>

 

The observationMedia element holds an ED datatype which is where the MIME goes

 

            <xs:complexType name="POCD_MT000040.ObservationMedia">
                       
<xs:sequence>
                                   
<xs:element name="realmCode" type="CS" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="typeId" type="POCD_MT000040.InfrastructureRoot.typeId" minOccurs="0"/>
                                   
<xs:element name="templateId" type="II" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="id" type="II" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="languageCode" type="CS" minOccurs="0"/>
                                   
<xs:element name="value" type="ED"/>
                                   
<xs:element name="subject" type="POCD_MT000040.Subject" minOccurs="0"/>
                                   
<xs:element name="specimen" type="POCD_MT000040.Specimen" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="performer" type="POCD_MT000040.Performer2" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="author" type="POCD_MT000040.Author" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="informant" type="POCD_MT000040.Informant12" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="participant" type="POCD_MT000040.Participant2" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="entryRelationship" type="POCD_MT000040.EntryRelationship" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="reference" type="POCD_MT000040.Reference" minOccurs="0" maxOccurs="unbounded"/>
                                   
<xs:element name="precondition" type="POCD_MT000040.Precondition" minOccurs="0" maxOccurs="unbounded"/>
                       
</xs:sequence>
                       
<xs:attribute name="ID" type="xs:ID"/>
                       
<xs:attribute name="nullFlavor" type="NullFlavor" use="optional"/>
                       
<xs:attribute name="classCode" type="ActClassObservation" use="required"/>
                       
<xs:attribute name="moodCode" type="ActMood" use="required"/>
           
</xs:complexType>

Note that we are finally down to the ED datatype which is essentially a way of representing MIME in ISO XML


  
<xs:complexType name="ED" mixed="true">
     
<xs:annotation>
        
<xs:documentation>
            Data that is primarily intended for human interpretation
            or for further machine processing is outside the scope of
            HL7. This includes unformatted or formatted written language,
            multimedia data, or structured information as defined by a
            different standard (e.g., XML-signatures.)  Instead of the
            data itself, an ED may contain
            only a reference (see TEL.) Note
            that the ST data type is a
            specialization of the ED data type
            when the ED media type is text/plain.
        
</xs:documentation>
     
</xs:annotation>
     
<xs:complexContent>
        
<xs:extension base="BIN">
           
<xs:sequence>
              
<xs:element name="reference" type="TEL" minOccurs="0" maxOccurs="1">
                 
<xs:annotation>
                    
<xs:documentation>
                        A telecommunication address (TEL), such as a URL
                        for HTTP or FTP, which will resolve to precisely
                        the same binary data that could as well have been
                        provided as inline data.
                    
</xs:documentation>
                 
</xs:annotation>
              
</xs:element>
              
<xs:element name="thumbnail" minOccurs="0" maxOccurs="1" type="thumbnail"/>
           
</xs:sequence>
           
<xs:attribute name="mediaType" type="cs" use="optional" default="text/plain">
              
<xs:annotation>
                 
<xs:documentation>
                     Identifies the type of the encapsulated data and
                     identifies a method to interpret or render the data.
                  
</xs:documentation>
              
</xs:annotation>
           
</xs:attribute>
           
<xs:attribute name="language" type="cs" use="optional">
              
<xs:annotation>
                 
<xs:documentation>
                     For character based information the language property
                     specifies the human language of the text.
                 
</xs:documentation>
              
</xs:annotation>
           
</xs:attribute>
           
<xs:attribute name="compression" type="CompressionAlgorithm" use="optional">
              
<xs:annotation>
                 
<xs:documentation>
                     Indicates whether the raw byte data is compressed,
                     and what compression algorithm was used.
                  
</xs:documentation>
              
</xs:annotation>
           
</xs:attribute>
           
<xs:attribute name="integrityCheck" type="bin" use="optional">
              
<xs:annotation>
                 
<xs:documentation>
                     The integrity check is a short binary value representing
                     a cryptographically strong checksum that is calculated
                     over the binary data. The purpose of this property, when
                     communicated with a reference is for anyone to validate
                     later whether the reference still resolved to the same
                     data that the reference resolved to when the encapsulated
                     data value with reference was created.
                 
</xs:documentation>
              
</xs:annotation>
           
</xs:attribute>
           
<xs:attribute name="integrityCheckAlgorithm" type="IntegrityCheckAlgorithm" use="optional" default="SHA-1">
              
<xs:annotation>
                 
<xs:documentation>
                     Specifies the algorithm used to compute the
                     integrityCheck value.
                 
</xs:documentation>
              
</xs:annotation>
           
</xs:attribute>
         
</xs:extension>
     
</xs:complexContent>
  
</xs:complexType>

 

   <xs:complexType name="BIN" abstract="true" mixed="true">
     
<xs:annotation>
        
<xs:documentation>
            Binary data is a raw block of bits. Binary data is a
            protected type that MUST not be used outside the data
            type specification.
        
</xs:documentation>
     
</xs:annotation>
     
<xs:complexContent>
        
<xs:extension base="ANY">
           
<xs:attribute name="representation" use="optional" type="BinaryDataEncoding" default="TXT">
              
<xs:annotation>
                 
<xs:documentation>
                     Specifies the representation of the binary data that
                     is the content of the binary data value.
                 
</xs:documentation>
              
</xs:annotation>
           
</xs:attribute>
        
</xs:extension>
     
</xs:complexContent>
  
</xs:complexType>
  
<xs:simpleType name="bin">
     
<xs:annotation>
        
<xs:documentation>
            Binary data is a raw block of bits. Binary data is a
            protected type that MUST not be used outside the data
            type specification.
        
</xs:documentation>
     
</xs:annotation>
     
<xs:restriction base="xs:base64Binary"/>
  
</xs:simpleType>
  
<xs:simpleType name="BinaryDataEncoding">
     
<xs:restriction base="xs:NMTOKEN">
        
<xs:enumeration value="B64"/>
        
<xs:enumeration value="TXT"/>
     
</xs:restriction>
  
</xs:simpleType>

Evgeniy Gladyshev

unread,
Apr 5, 2013, 11:11:23 AM4/5/13
to vr...@googlegroups.com

I would vote for including RootUID in the standard.

As for mime types, I guess, I was talking about this attribute from full CDA,
<xs:attribute name="mediaType" type="cs" use="optional" default="text/plain">

I would not go as far as adding support for embedding binary bits into reports directly, but having a standard way of referencing them would be helpful along with some direct support for some common textual presentation formats like html.

Thanks,
-Eugene

Reply all
Reply to author
Forward
0 new messages