Allow parsing of RSQuot

This commit is contained in:
James 2017-01-29 15:49:10 -05:00
parent 97f1e55131
commit b66aa9761e
4 changed files with 37 additions and 7 deletions

View File

@ -48,7 +48,6 @@ package org.hl7.fhir.utilities.xhtml;
* #L% * #L%
*/ */
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
@ -378,10 +377,12 @@ public class XhtmlParser {
} }
return result; return result;
} }
public XhtmlDocument parse(String source, String entryName) throws FHIRFormatError, IOException { public XhtmlDocument parse(String source, String entryName) throws FHIRFormatError, IOException {
rdr = new StringReader(source); rdr = new StringReader(source);
return parse(entryName); return parse(entryName);
} }
private void parseAttributes(XhtmlNode node) throws FHIRFormatError, IOException { private void parseAttributes(XhtmlNode node) throws FHIRFormatError, IOException {
while (Character.isWhitespace(peekChar())) while (Character.isWhitespace(peekChar()))
readChar(); readChar();
@ -410,6 +411,7 @@ public class XhtmlParser {
readChar(); readChar();
} }
} }
private String parseAttributeValue(char term) throws IOException, FHIRFormatError { private String parseAttributeValue(char term) throws IOException, FHIRFormatError {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
while (peekChar() != '\0' && peekChar() != '>' && (term != '\0' || peekChar() != '/') && peekChar() != term) { while (peekChar() != '\0' && peekChar() != '>' && (term != '\0' || peekChar() != '/') && peekChar() != term) {
@ -422,6 +424,7 @@ public class XhtmlParser {
readChar(); readChar();
return b.toString(); return b.toString();
} }
private void parseElement(XhtmlNode parent, List<XhtmlNode> parents, NSMap nsm) throws IOException, FHIRFormatError { private void parseElement(XhtmlNode parent, List<XhtmlNode> parents, NSMap nsm) throws IOException, FHIRFormatError {
QName name = new QName(readName()); QName name = new QName(readName());
XhtmlNode node = parent.addTag(name.getName()); XhtmlNode node = parent.addTag(name.getName());
@ -438,6 +441,7 @@ public class XhtmlParser {
parseElementInner(node, newParents, nsm); parseElementInner(node, newParents, nsm);
} }
} }
private void parseElementInner(XhtmlNode node, List<XhtmlNode> parents, NSMap nsm) throws FHIRFormatError, IOException { private void parseElementInner(XhtmlNode node, List<XhtmlNode> parents, NSMap nsm) throws FHIRFormatError, IOException {
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
while (peekChar() != '\0' && !parents.contains(unwindPoint) && !(node == unwindPoint)) { while (peekChar() != '\0' && !parents.contains(unwindPoint) && !(node == unwindPoint)) {
@ -488,6 +492,7 @@ public class XhtmlParser {
} }
addTextNode(node, s); addTextNode(node, s);
} }
private XhtmlNode parseFragment() throws IOException, FHIRException { private XhtmlNode parseFragment() throws IOException, FHIRException {
skipWhiteSpace(); skipWhiteSpace();
if (peekChar() != '<') if (peekChar() != '<')
@ -558,6 +563,8 @@ public class XhtmlParser {
s.append(XhtmlNode.NBSP); s.append(XhtmlNode.NBSP);
else if (c.equals("amp")) else if (c.equals("amp"))
s.append('&'); s.append('&');
else if (c.equals("rsquo"))
s.append('');
else if (c.equals("gt")) else if (c.equals("gt"))
s.append('>'); s.append('>');
else if (c.equals("lt")) else if (c.equals("lt"))

View File

@ -29,6 +29,14 @@ public class XhtmlDtTest {
} }
@Test
public void testParseRsquo() {
XhtmlDt dt = new XhtmlDt();
dt.setValueAsString("It&rsquo;s January again");
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">It&rsquo;s January again</div>", dt.getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">Its January again</div>", new XhtmlDt().setValue(dt.getValue()).getValueAsString());
}
@Test @Test
public void testRoundtrip() { public void testRoundtrip() {
String div = "<div xmlns=\"http://www.w3.org/1999/xhtml\"><pre>\r\n&lt;<a title=\"Prospective warnings of potential issues when providing care to the patient.\" class=\"dict\" href=\"alert-definitions.html#Alert\"><b>Alert</b></a> xmlns=&quot;http://hl7.org/fhir&quot;&gt; <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n &lt;!-- from <a href=\"resources.html\">Resource</a>: <a href=\"extensibility.html\">extension</a>, <a href=\"extensibility.html#modifierExtension\">modifierExtension</a>, language, <a href=\"narrative.html#Narrative\">text</a>, and <a href=\"references.html#contained\">contained</a> --&gt;\r\n &lt;<a title=\"Identifier assigned to the alert for external use (outside the FHIR environment).\" class=\"dict\" href=\"alert-definitions.html#Alert.identifier\"><b>identifier</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..*</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#Identifier\">Identifier</a></span> <span style=\"color: navy\">Business identifier</span><span style=\"color: Gray\"> --&gt;</span>&lt;/identifier&gt;\r\n &lt;<a title=\"Allows an alert to be divided into different categories like clinical, administrative etc.\" class=\"dict\" href=\"alert-definitions.html#Alert.category\"><b>category</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#CodeableConcept\">CodeableConcept</a></span> <span style=\"color: navy\">Clinical, administrative, etc.</span><span style=\"color: Gray\"> --&gt;</span>&lt;/category&gt;\r\n &lt;<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\"><a style=\"color: navy\" href=\"alert-status.html\">active | inactive | entered in error</a></span><span style=\"color: Gray\"> --&gt;</span>\r\n &lt;<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"patient.html#Patient\">Patient</a>)</span> <span style=\"color: navy\">Who is alert about?</span><span style=\"color: Gray\"> --&gt;</span>&lt;/subject&gt;\r\n &lt;<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"practitioner.html#Practitioner\">Practitioner</a>|<a href=\"patient.html#Patient\">Patient</a>|<a href=\"device.html#Device\">Device</a>)</span> <span style=\"color: navy\">Alert creator</span><span style=\"color: Gray\"> --&gt;</span>&lt;/author&gt;\r\n &lt;<a title=\"The textual component of the alert to display to the user.\" class=\"dict\" href=\"alert-definitions.html#Alert.note\"><b>note</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --&gt;</span>\r\n&lt;/Alert&gt;\r\n</pre></div>"; String div = "<div xmlns=\"http://www.w3.org/1999/xhtml\"><pre>\r\n&lt;<a title=\"Prospective warnings of potential issues when providing care to the patient.\" class=\"dict\" href=\"alert-definitions.html#Alert\"><b>Alert</b></a> xmlns=&quot;http://hl7.org/fhir&quot;&gt; <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n &lt;!-- from <a href=\"resources.html\">Resource</a>: <a href=\"extensibility.html\">extension</a>, <a href=\"extensibility.html#modifierExtension\">modifierExtension</a>, language, <a href=\"narrative.html#Narrative\">text</a>, and <a href=\"references.html#contained\">contained</a> --&gt;\r\n &lt;<a title=\"Identifier assigned to the alert for external use (outside the FHIR environment).\" class=\"dict\" href=\"alert-definitions.html#Alert.identifier\"><b>identifier</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..*</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#Identifier\">Identifier</a></span> <span style=\"color: navy\">Business identifier</span><span style=\"color: Gray\"> --&gt;</span>&lt;/identifier&gt;\r\n &lt;<a title=\"Allows an alert to be divided into different categories like clinical, administrative etc.\" class=\"dict\" href=\"alert-definitions.html#Alert.category\"><b>category</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#CodeableConcept\">CodeableConcept</a></span> <span style=\"color: navy\">Clinical, administrative, etc.</span><span style=\"color: Gray\"> --&gt;</span>&lt;/category&gt;\r\n &lt;<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\"><a style=\"color: navy\" href=\"alert-status.html\">active | inactive | entered in error</a></span><span style=\"color: Gray\"> --&gt;</span>\r\n &lt;<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"patient.html#Patient\">Patient</a>)</span> <span style=\"color: navy\">Who is alert about?</span><span style=\"color: Gray\"> --&gt;</span>&lt;/subject&gt;\r\n &lt;<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"practitioner.html#Practitioner\">Practitioner</a>|<a href=\"patient.html#Patient\">Patient</a>|<a href=\"device.html#Device\">Device</a>)</span> <span style=\"color: navy\">Alert creator</span><span style=\"color: Gray\"> --&gt;</span>&lt;/author&gt;\r\n &lt;<a title=\"The textual component of the alert to display to the user.\" class=\"dict\" href=\"alert-definitions.html#Alert.note\"><b>note</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --&gt;</span>\r\n&lt;/Alert&gt;\r\n</pre></div>";

View File

@ -3,10 +3,12 @@ package ca.uhn.fhir.model;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.hl7.fhir.dstu3.model.ExplanationOfBenefit; import org.hl7.fhir.dstu3.model.ExplanationOfBenefit;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Test; import org.junit.Test;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
public class XhtmlNodeTest { public class XhtmlNodeTest {
@ -20,6 +22,15 @@ public class XhtmlNodeTest {
private static FhirContext ourCtx = FhirContext.forDstu3(); private static FhirContext ourCtx = FhirContext.forDstu3();
@Test
public void testParseRsquo() {
XhtmlNode dt = new XhtmlNode();
dt.setValueAsString("It&rsquo;s January again");
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">Its January again</div>", dt.getValueAsString());
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">Its January again</div>", new XhtmlNode().setValue(dt.getValue()).getValueAsString());
}
/** /**
* See #443 * See #443
*/ */

View File

@ -237,6 +237,10 @@
Declared extensions with multiple type() options listed in the @Child Declared extensions with multiple type() options listed in the @Child
annotation caused a crash on startup. Now this is supported. annotation caused a crash on startup. Now this is supported.
</action> </action>
<action type="add">
STU3 XHTML parser for narrative choked if the narrative contained
an <![CDATA[<code>&amp;rsquot;</code>]]> entity string.
</action>
</release> </release>
<release version="2.1" date="2016-11-11"> <release version="2.1" date="2016-11-11">
<action type="add"> <action type="add">