Allow parsing of RSQuot
This commit is contained in:
parent
97f1e55131
commit
b66aa9761e
|
@ -38,7 +38,7 @@ package org.hl7.fhir.utilities.xhtml;
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@ -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"))
|
||||||
|
@ -860,12 +867,12 @@ public class XhtmlParser {
|
||||||
StartElement firstEvent = (StartElement) xpp.nextEvent();
|
StartElement firstEvent = (StartElement) xpp.nextEvent();
|
||||||
res.setName(firstEvent.getSchemaType().getLocalPart());
|
res.setName(firstEvent.getSchemaType().getLocalPart());
|
||||||
|
|
||||||
for (Iterator<?> attrIter = firstEvent.getAttributes(); attrIter.hasNext(); ) {
|
for (Iterator<?> attrIter = firstEvent.getAttributes(); attrIter.hasNext();) {
|
||||||
Attribute nextAttr = (Attribute) attrIter.next();
|
Attribute nextAttr = (Attribute) attrIter.next();
|
||||||
if (attributeIsOk(firstEvent.getName().getLocalPart(), nextAttr.getName().getLocalPart(), nextAttr.getValue()))
|
if (attributeIsOk(firstEvent.getName().getLocalPart(), nextAttr.getName().getLocalPart(), nextAttr.getValue()))
|
||||||
res.getAttributes().put(nextAttr.getName().getLocalPart(), nextAttr.getValue());
|
res.getAttributes().put(nextAttr.getName().getLocalPart(), nextAttr.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
while (xpp.hasNext()) {
|
while (xpp.hasNext()) {
|
||||||
XMLEvent nextEvent = xpp.nextEvent();
|
XMLEvent nextEvent = xpp.nextEvent();
|
||||||
int eventType = nextEvent.getEventType();
|
int eventType = nextEvent.getEventType();
|
||||||
|
@ -873,11 +880,11 @@ public class XhtmlParser {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (eventType == XMLEvent.CHARACTERS) {
|
if (eventType == XMLEvent.CHARACTERS) {
|
||||||
res.addText(((Characters)xpp).getData());
|
res.addText(((Characters) xpp).getData());
|
||||||
} else if (eventType == XMLEvent.COMMENT) {
|
} else if (eventType == XMLEvent.COMMENT) {
|
||||||
res.addComment(((Comment)xpp).getText());
|
res.addComment(((Comment) xpp).getText());
|
||||||
} else if (eventType == XMLEvent.START_ELEMENT) {
|
} else if (eventType == XMLEvent.START_ELEMENT) {
|
||||||
StartElement nextStart = (StartElement)nextEvent;
|
StartElement nextStart = (StartElement) nextEvent;
|
||||||
if (elementIsOk(nextStart.getName().getLocalPart())) {
|
if (elementIsOk(nextStart.getName().getLocalPart())) {
|
||||||
res.getChildNodes().add(parseNode(xpp));
|
res.getChildNodes().add(parseNode(xpp));
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,14 @@ public class XhtmlDtTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseRsquo() {
|
||||||
|
XhtmlDt dt = new XhtmlDt();
|
||||||
|
dt.setValueAsString("It’s January again");
|
||||||
|
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">It’s January again</div>", dt.getValueAsString());
|
||||||
|
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">It’s 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<<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="http://hl7.org/fhir"> <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n <!-- 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> -->\r\n <<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>><span style=\"color: Gray\"><!--</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\"> --></span></identifier>\r\n <<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>><span style=\"color: Gray\"><!--</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\"> --></span></category>\r\n <<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value="[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]"/><span style=\"color: Gray\"><!--</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\"> --></span>\r\n <<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>><span style=\"color: Gray\"><!--</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\"> --></span></subject>\r\n <<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>><span style=\"color: Gray\"><!--</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\"> --></span></author>\r\n <<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="[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]"/><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --></span>\r\n</Alert>\r\n</pre></div>";
|
String div = "<div xmlns=\"http://www.w3.org/1999/xhtml\"><pre>\r\n<<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="http://hl7.org/fhir"> <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n <!-- 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> -->\r\n <<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>><span style=\"color: Gray\"><!--</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\"> --></span></identifier>\r\n <<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>><span style=\"color: Gray\"><!--</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\"> --></span></category>\r\n <<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value="[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]"/><span style=\"color: Gray\"><!--</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\"> --></span>\r\n <<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>><span style=\"color: Gray\"><!--</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\"> --></span></subject>\r\n <<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>><span style=\"color: Gray\"><!--</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\"> --></span></author>\r\n <<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="[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]"/><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --></span>\r\n</Alert>\r\n</pre></div>";
|
||||||
|
|
|
@ -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’s January again");
|
||||||
|
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">It’s January again</div>", dt.getValueAsString());
|
||||||
|
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">It’s January again</div>", new XhtmlNode().setValue(dt.getValue()).getValueAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See #443
|
* See #443
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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>&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">
|
||||||
|
|
Loading…
Reference in New Issue