Commit 63459eee authored by R.W.Majeed's avatar R.W.Majeed

fixed export XPath evaluation

parent 27662b11
package de.sekmi.histream.export;
import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import de.sekmi.histream.io.GroupedXMLWriter;
public class DwhNamespaceResolver implements NamespaceContext{
@Override
public String getNamespaceURI(String prefix) {
if( prefix == null ){
throw new IllegalArgumentException("prefix is null");
}else if( prefix.equals(XMLConstants.DEFAULT_NS_PREFIX) ){
return GroupedXMLWriter.NAMESPACE;
}else{
return XMLConstants.NULL_NS_URI;
}
}
@Override
public String getPrefix(String namespaceURI) {
throw new UnsupportedOperationException();
}
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
......@@ -10,6 +10,7 @@ import de.sekmi.histream.ObservationSupplier;
import de.sekmi.histream.export.config.ExportDescriptor;
import de.sekmi.histream.export.config.ExportException;
import de.sekmi.histream.io.Streams;
import de.sekmi.histream.xml.NamespaceResolver;
public class TableExportFactory {
private ExportDescriptor desc;
......@@ -19,7 +20,7 @@ public class TableExportFactory {
public TableExportFactory(ExportDescriptor desc){
this.desc = desc;
factory = XPathFactory.newInstance();
ns = new DwhNamespaceResolver();
ns = new NamespaceResolver();
}
private XPath createXPath(){
......
......@@ -3,6 +3,7 @@ package de.sekmi.histream.export;
import java.io.IOException;
import java.util.Objects;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
......
......@@ -13,7 +13,9 @@ import javax.xml.transform.dom.DOMResult;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import de.sekmi.histream.ObservationException;
import de.sekmi.histream.ext.Patient;
......@@ -38,26 +40,31 @@ public abstract class VisitFragmentParser extends GroupedXMLWriter {
setDOMWriter(doc);
}
private void fixNamespaces(DocumentFragment fragment){
//fragment.setPrefix(null);
// cannot do this
}
private void setDOMWriter(Node node) throws XMLStreamException{
Result result = new DOMResult(node);
writer = factory.createXMLStreamWriter(result);
// XXX need this?
writer.setDefaultNamespace(ObservationImpl.XML_NAMESPACE);
writer.setPrefix(XMLConstants.DEFAULT_NS_PREFIX, ObservationImpl.XML_NAMESPACE);
writer.setPrefix("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
//writer.setDefaultNamespace(ObservationImpl.XML_NAMESPACE);
//writer.setPrefix(XMLConstants.DEFAULT_NS_PREFIX, ObservationImpl.XML_NAMESPACE);
//writer.setPrefix("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
}
private void createDocument() throws ParserConfigurationException{
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
f.setNamespaceAware(true);
f.setIgnoringComments(true);
f.setCoalescing(true);
f.setIgnoringElementContentWhitespace(true);
f.setNamespaceAware(true);
DocumentBuilder builder = f.newDocumentBuilder();
doc = builder.newDocument();
// doc.getDomConfig().setParameter("namespaces", true);
// doc.getDomConfig().setParameter("namespace-declarations", true);
doc.getDomConfig().setParameter("namespaces", true);
doc.getDomConfig().setParameter("namespace-declarations", true);
//return doc;
}
......@@ -79,6 +86,7 @@ public abstract class VisitFragmentParser extends GroupedXMLWriter {
protected void beginPatient(Patient patient) throws ObservationException {
// write patient info to patient fragment
currentPatient = doc.createDocumentFragment();
try {
setDOMWriter(currentPatient);
} catch (XMLStreamException e) {
......@@ -91,6 +99,7 @@ public abstract class VisitFragmentParser extends GroupedXMLWriter {
protected void beginEncounter(Visit visit) throws ObservationException {
if( firstVisit == false ){
// patient fragment was parsed
fixNamespaces(currentPatient);
patientFragment(currentPatient.getFirstChild());
firstVisit = true;
}
......@@ -112,6 +121,7 @@ public abstract class VisitFragmentParser extends GroupedXMLWriter {
super.endEncounter(visit);
// encounter is finished
// fragment should contain exactly one node -> the visit
fixNamespaces(currentVisit);
Node node = currentVisit.getFirstChild();
Objects.requireNonNull(node);
visitFragment(currentVisit.getFirstChild());
......
......@@ -4,7 +4,6 @@ import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement(name="export")
@XmlAccessorType(XmlAccessType.NONE)
......
......@@ -5,13 +5,14 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.junit.Assert;
import org.junit.Test;
import org.w3c.dom.Node;
import de.sekmi.histream.ObservationSupplier;
import de.sekmi.histream.export.DwhNamespaceResolver;
import de.sekmi.histream.export.VisitFragmentSupplier;
import de.sekmi.histream.io.FileObservationProviderTest;
import de.sekmi.histream.xml.NamespaceResolver;
import de.sekmi.histream.xml.XMLUtils;
public class TestVisitFragmentParser {
......@@ -38,12 +39,14 @@ public class TestVisitFragmentParser {
private void testXPath(Node visit) throws XPathExpressionException{
XPathFactory f = XPathFactory.newInstance();
XPath xp = f.newXPath();
xp.setNamespaceContext(new DwhNamespaceResolver());
// XXX namespace resolver is not working
String ret = (String)xp.evaluate("namespace-uri(./*[6])", visit, XPathConstants.STRING);
System.out.println("XPath="+ret);
ret = (String)xp.evaluate("count(fact)", visit, XPathConstants.STRING);
System.out.println("Facts:"+ret);
xp.setNamespaceContext(new NamespaceResolver());
// selectors always need a prefix in XPath 1
String ret;
// ret = (String)xp.evaluate("namespace-uri(./*[6])", visit, XPathConstants.STRING);
// System.out.println("XPath="+ret);
ret = (String)xp.evaluate("count(eav:fact)", visit, XPathConstants.STRING);
// System.out.println("Facts:"+ret);
Assert.assertEquals("12", ret);
}
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:export xmlns:ns2="http://sekmi.de/ns/histream/export-v1">
<export xmlns="http://sekmi.de/ns/histream/export-v1"
xmlns:eav="http://sekmi.de/histream/ns/eav-data">
<concepts>
<group class="diag">
<concept wildcard-notation="ICD10:*"/>
......@@ -9,15 +10,16 @@
</concepts>
<patient-table>
<column header="pid" xpath="@id"/>
<column header="dob" xpath="birthdate"/>
<column header="sex" xpath="gender"/>
<column header="dob" xpath="eav:birthdate"/>
<column header="sex" xpath="eav:gender"/>
<column header="modified" xpath="eav:source/@timestamp"/>
</patient-table>
<visit-table>
<column header="vid" xpath="@id"/>
<column header="start" xpath="start"/>
<column header="f_start" xpath="fact[@concept='T:full']/@start"/>
<column header="f_end" xpath="fact[@concept='T:full']/@end"/>
<column header="f_loc" xpath="fact[@concept='T:full']/@location"/>
<column header="f_val" xpath="fact[@concept='T:full']/value"/>
<column header="start" xpath="eav:start"/>
<column header="f_start" xpath="eav:fact[@concept='T:full']/@start"/>
<column header="f_end" xpath="eav:fact[@concept='T:full']/@end"/>
<column header="f_loc" xpath="eav:fact[@concept='T:full']/@location"/>
<column header="f_val" xpath="eav:fact[@concept='T:full']/eav:value"/>
</visit-table>
</ns2:export>
</export>
......@@ -31,8 +31,8 @@ to construct table data.
<patient-table>
<column header="pid" xpath="@id"/>
<column header="birthdate" xpath="birthdate"/>
<column header="gender" xpath="gender"/>
<column header="birthdate" xpath="eav:birthdate"/>
<column header="gender" xpath="eav:gender"/>
</patient-table>
<visit-table>
<!-- context for XPath expressions is each visit node -->
......@@ -41,14 +41,14 @@ to construct table data.
<column header="visit" xpath="@id"/>
<!-- concepts for the visit table must occur only once
per visit and may not repeat -->
<column header="start" xpath="start"/>
<column header="start" xpath="eav:start"/>
<!-- What is better? -->
<!-- (a) First column, then concepts with value -->
<column header="diagnostik_labort_ts" xpath="facts/fact[@class='d_lab']/@start"/>
<column header="diagnostik_labort" xpath="facts/fact[@class='d_lab']/@concept"/>
<column header="diagnostik_labort_ts" xpath="eav:fact[@class='d_lab']/@start"/>
<column header="diagnostik_labort" xpath="eav:fact[@class='d_lab']/@concept"/>
<!-- (b) first concepts then columns with value -->
<column header="diagnostik_labort_ts" xpath="facts/fact[@class='d_lab']/@start"/>
<column header="diagnostik_labort" xpath="facts/fact[@class='d_lab']/modifier[@code='OPB' or @code='PB']/@code"/>
<column header="diagnostik_labort_ts" xpath="eav:fact[@class='d_lab']/@start"/>
<column header="diagnostik_labort" xpath="eav:fact[@class='d_lab']/eav:modifier[@code='OPB' or @code='PB']/@code"/>
<!-- We want this:
6:NEG -> not tested
6/mod=OPB -> tested non pathological
......@@ -62,6 +62,6 @@ to construct table data.
<column header="visit" xpath="visit-ref"/>
<column header="start" type="@start"/>
<column header="code" type="@concept"/>
<column header="primary" xpath="modifier[@code='fuehrend']/@code"/>
<column header="primary" xpath="eav:modifier[@code='fuehrend']/@code"/>
</eav-table>
</export>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment