php-fhir
php-fhir copied to clipboard
HTML output for a narrative element
I am trying to generate a narrative for a patient but the generated xml doesnt look correct.
Below is the generated XML where the actual text is added to a value attribute of the div element and the XML namespace is missing.
<text> <status value="generated"/> <div value="<p>Voorbeeld van een 'Patient' zoals verder samengesteld tijdens de HL7 WGM NL 15-04-2016 jl. Deze discussie heeft diverse uitzoekpunten opgeleverd zoals hier gedocumenteerd.</p>"/> </text>
When I change the following line in FHIRNarrative.php
$divElement = $sxe->addChild('div', (string)$this->div); $divElement->addAttribute('value', (string)$this->div);
to
$divElement = $sxe->addChild('div', (string)$this->div, "http://www.w3.org/1999/xhtml"); //$divElement->addAttribute('value', (string)$this->div);
The output does looks better besides that the <p>
elements are encoded with htmlentities.
<text> <status value="generated"/> <div xmlns="http://www.w3.org/1999/xhtml"><p>Voorbeeld van een 'Patient' zoals verder samengesteld tijdens de HL7 WGM NL 15-04-2016 jl. Deze discussie heeft diverse uitzoekpunten opgeleverd zoals hier gedocumenteerd.</p> </div> </text>
I following this example as a reference https://simplifier.net/NictizSTU3/nl-core-patient-example-1/~overview The XSD release is STU3
@leonrenkema: hey, thanks for the suggestion. Unfortunately I've not had a great deal of time to implement a lot of the features I'd like to have in this lib, but I have come up with a quick fix that I hope will be satisfactory.
I have modified code identified as "html" to serialize as an XML CDATA element under their parent element.
So, this:
<text>
<status value="generated"/>
<div value="<div xmlns="http://www.w3.org/1999/xhtml"> <table> <tbody> <tr> <td>Name</td> <td>Peter James <b>Chalmers</b> ("Jim")</td> </tr> <tr> <td>Address</td> <td>534 Erewhon, Pleasantville, Vic, 3999</td> </tr> <tr> <td>Contacts</td> <td>Home: unknown. Work: (03) 5555 6473</td> </tr> <tr> <td>Id</td> <td>MRN: 12345 (Acme Healthcare)</td> </tr> </tbody> </table> </div>"/>
</text>
will now be this:
<text>
<status value="generated"/>
<![CDATA[<div xmlns="http://www.w3.org/1999/xhtml"> <table> <tbody> <tr> <td>Name</td> <td>Peter James <b>Chalmers</b> ("Jim")</td> </tr> <tr> <td>Address</td> <td>534 Erewhon, Pleasantville, Vic, 3999</td> </tr> <tr> <td>Contacts</td> <td>Home: unknown. Work: (03) 5555 6473</td> </tr> <tr> <td>Id</td> <td>MRN: 12345 (Acme Healthcare)</td> </tr> </tbody> </table> </div>]]>
</text>
I have pushed the changes to master. Please check it out and see if this solution works for you. If it does, I will make a new tag and update the generated library as well.
Thanks for the fix but I'dont think it is correct this way. The div element is missing now. I think the desired output should be the following.
<text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml"> <table> <tbody> <tr> <td>Name</td> <td>Peter James <b>Chalmers</b> ("Jim")</td> </tr> <tr> <td>Address</td> <td>534 Erewhon, Pleasantville, Vic, 3999</td> </tr> <tr> <td>Contacts</td> <td>Home: unknown. Work: (03) 5555 6473</td> </tr> <tr> <td>Id</td> <td>MRN: 12345 (Acme Healthcare)</td> </tr> </tbody> </table> </div>
</text>
I'm playing around with the generator and trying to generate it the correct way, but SimpleXML is sometimes too simple for these complex use-cases. I will look if I can make a PR that will fix this.
@leonrenkema: the div element isn't missing, it is inside the CDATA block. It is generally not a great idea to put raw HTML inside of an XML document as HTML can be written in a much less strict fashion than XML.
Yes, i know. When I look at the FHIR spec it requires a div element within the xhtml namespace. https://www.hl7.org/fhir/narrative.html The div element as cdata does not validate against the XSD.
Ah, you are entirely correct. I also do not like my current implementation as it requires php dom to be installed as well as php xml. I have found a few clever solutions to this issue, and will implement one asap.
Tnx. I have worked a lot with xmlwriter in php and that is more flexible than simplexml for generating this kind of xml. I have used it for generating hl7v3 documents.
Alrighty, I have pushed an update. I'm not certain I'm happy with the implementation, but if it works for you I will leave as-is until an issue arises.
The output now looks like this:
<text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml"> <table> <tbody> <tr> <td>Name</td><td>Peter James ("Jim")<b>Chalmers</b></td></tr><tr> <td>Address</td><td>534 Erewhon, Pleasantville, Vic, 3999</td></tr><tr> <td>Contacts</td><td>Home: unknown. Work: (03) 5555 6473</td></tr><tr> <td>Id</td><td>MRN: 12345 (Acme Healthcare)</td></tr></tbody></table></div>
</text>
Great, is it intended that I have to use it this way because of the namespacing?
$text->setDiv("<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Example Narrative</p></div>");
I'm not sure what you mean by your last comment, are you asking why I don't inject the namespace myself?
Yes, what I mean is why there is a difference between the setStatus and setDiv. setStatus generates the
$text->setStatus($narrativeStatus);
$text->setDiv("<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Example Narrative</p></div>");
When I use setDiv('<p>Example</p>')
the generated xml is not valid because the <div>
element is missing.
So in this context I'm hesitant to assume the existence of the <div>
element. I don't want to assume what attributes you apply to the element, what xsd you want to use, etc. I think it makes much more sense for a user to actually define the entirety of the HTML.
Okay, sounds logical. From the specification I see that an optional lang
attribute can also be added to the div element so that is possible this way.
Thanks, I think this issue can be resolved.
It looks like this fix is reverted, we are seeing htmlencoded xml inside the <div>
when serializing to XML.
The JSON looks good.
@leonkrema thanks for reporting this. one question: are you pulling from master? if so, i am in the process of replacing SimpleXML with DOMDocument for xml manipulation, and it is not quite finished yet.
I unfortunately won’t have time to continue work on this until later in the week, so for the moment it may be better to use the latest tagged version.
@leonrenkrema sorry used my phone to comment, got your name wrong :/
@leonrenkema I'm not sure if you're still using this package, but I have updated master with a version that should address this for you.
If you could, please give it a try and let me know if it addresses the issue for you.
Hi,
I have tested it against the latest master and the R4 specs. But it is not working as expected.
$narrative = new FHIRNarrative([
'div' => new FHIRXHTML('This is a simple example with only plain text')
]);
This is what I am getting.
<div>
<html>
<body>
<p>This is a simple example with only plain text</p>
</body>
</html>
</div>
The json variant looks like this
{"div":"<html><body><p>This is a simple example with only plain text<\/p><\/body><\/html>"}
To be honest I do not get where the <body>
and <html>
tags come from.
For comparison when I generate the same xml with the C# library it produces the output like this:
var narrative = new Narrative();
narrative.Div = "This is a simple example with only plain text";
var serializer = new FhirXmlSerializer();
var xmlText = serializer.SerializeToString(narrative);
Console.WriteLine(xmlText);
<Narrative xmlns="http://hl7.org/fhir">
<div xmlns="http://www.w3.org/1999/xhtml">This is a simple example with only plain text</div>
</Narrative>
This is the output that I should expect.
oh very weird...alright, i'll take a look at that. that xml type was written fairly quickly, so I'm sure i messed something up somewhere.
This has been addressed by #100 will (finally) close once v3 reaches release
@leonrenkema: I have release v3.0.0 that allows you to specify an arbitrary HTML value for the Narrative div. Can you please try it out, see if it addresses this issue for you?