i try to read from a XML document via the CodeSynthesis XSD generated files (.cxx/.hxx) and have this code:
1-> char* xmlFile = "C:\\Work\\MPRawDataExample.xml";
2-> auto_ptr<MPRawDataFile> f = MPRawDataFile_(xmlFile);
3-> cout << f->MPRawDataFileMeta().PatientID() << endl;
Now on line 2 following error occurs:
unterminated entity reference "D" thrown from the xsd::cxx::tree::error_handler<C>
The file really exists there, also checked out this but hasnt helped
Has maybe someone a solution for this or another way how to read out from a XML-file?
-> Solved. XSD-file wasnt referenced correctly in the xml file, but now this below:
Update:
wrong part in XML-file:
<AdditionalInformation>
<Info name="Ag" value="225.0/220.5"></Info>
<Info name="Vel" value="24.0/22.1"></Info>
<Info name="CC" value="0.999"></Info>
<Info name="AUC" value="1026/1159"></Info>
<Info name="Abbr. from mean" value="1.987"></Info>
<Info name="Base" value="1484/1501"></Info>
<Info name="End" value="1787/1795"></Info>
</AdditionalInformation>
restrictions from xsd:
<xs:simpleType name="ST_Info">
<xs:restriction base="xs:string">
<xs:enumeration value="0.999"/>
<xs:enumeration value="1.987"/>
<xs:enumeration value="1026/1159"/>
<xs:enumeration value="1484/1501"/>
<xs:enumeration value="1787/1795"/>
<xs:enumeration value="225.0/220.5 "/>
<xs:enumeration value="24.0/22.1"/>
</xs:restriction>
</xs:simpleType>
for each <Info> now i get the Error value "" not in enumeration
but the Value's that are in the XML are in the restriction-enumeration? or do i missunderstand something?
Turning my comments into an answer
Both the problems you list seem to be problems with the XML file itself, not with the parsing code. The first one looks like there's an entity reference &D without a matching ; or something.
The second one probably means that the restriction applies to the contents of the Item element (the text between its opening <Item> and closing </Item> tags), not to its attribute named value).
Related
I am working on writing rules using Schematron to validate data below. The requirement is to verify whether a patient has at least one encounter in the past 12 months. If there are multiple encounters per patient, use the last encounter.
<root>
<entry>
<resource>
<resourceType>Encounter</resourceType>
<subject>
<id>Patient/12345</id>
</subject>
<encounterDate>2018-04-10T10:00:00</encounterDate>
</resource>
</entry>
<entry>
<resource>
<resourceType>Encounter</resourceType>
<subject>
<id>Patient/abcde</id>
</subject>
<encounterDate>2020-04-10T10:00:00</encounterDate>
</resource>
</entry>
<entry>
<resource>
<resourceType>Encounter</resourceType>
<subject>
<id>Patient/abcde</id>
</subject>
<encounterDate>2019-05-10T10:00:00</encounterDate>
</resource>
</entry>
</root>
The above data should pass the validation because the latest encounter is less than a year ago.
What I want to know is, if I write a template that groups encounters together by patient id, is there a way to pass that template to the rule context? If not, is there any other way of doing it?
I am completely new to both xslt and Schematron and here is what I have so far:
<schema xmlns="http://purl.oclc.org/dsdl/schematron" >
<pattern>
<key name="patientId" match="entry" use="/resouce/subject/id/text()"/>
<template name="dateByPatient" match="entry">
<root>
<for-each select="resource/subject/id">
<patient >
<for-each select="key('patientId',text())">
<effectiveDateTime><value-of select="./resource/encounterDate"/></effectiveDateTime>
</for-each>
</patient>
</for-each>
</root>
</template>
<let name="template">
<dateByPatient/>
</let>
<let name="latest">
<root>
<for-each select="$template/root/patient">
<patient >
<sort select="effectiveDateTime" order="descending" />
<if test="position() = 1">
<effectiveDateTime><value-of select="effectiveDateTime" /></effectiveDateTime>
</if>
</patient>
</for-each>
</root>
</let>
<rule context="$latest/root/patient/effectiveDateTime">
<let name="days" value="days-from-duration(fn:current-dateTime() - xs:dateTime(text()))" />
<assert test="days-from-duration(fn:current-dateTime() - xs:dateTime(text())) < 365">
Encounter date more than a year : <value-of select="$days" /> days
</assert>
</rule>
</pattern>
</schema>
With XSLT 3 underlying you could use
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
<sch:ns prefix="map" uri="http://www.w3.org/2005/xpath-functions/map"/>
<sch:pattern>
<sch:rule context="root">
<sch:let name="groups"
value="let $encounter-resources := entry/resource[resourceType = 'Encounter']
return map:merge(
$encounter-resources
!
map {
data(subject/id) : xs:dateTime(encounterDate)
},
map { 'duplicates' : 'combine' }
)"/>
<sch:assert
test="every $patient in map:keys($groups)
satisfies
(current-dateTime() - max($groups($patient)))
lt xs:dayTimeDuration('P365D')">At least one patient with latest encounter more than a year ago.</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>
Or to output more detailed information and to only process resources with type Encounter:
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
<sch:ns prefix="map" uri="http://www.w3.org/2005/xpath-functions/map"/>
<sch:pattern>
<sch:rule context="root">
<sch:let name="groups"
value="let $encounter-resources := entry/resource[resourceType = 'Encounter']
return map:merge(
$encounter-resources
!
map {
data(subject/id) : xs:dateTime(encounterDate)
},
map { 'duplicates' : 'combine' }
)"/>
<sch:let name="failing-patients"
value="map:keys($groups)[(current-dateTime() - max($groups(.))) gt xs:dayTimeDuration('P365D')]"/>
<sch:report
test="exists($failing-patients)">Patients <sch:value-of select="$failing-patients"/> with latest encounter more than a year ago.</sch:report>
</sch:rule>
</sch:pattern>
</sch:schema>
I don't think you can mix Schematron and XSLT as freely as your code tries, you would need to set up an XProc pipeline to use p:xslt to group the original input and then a validation step to validate with Schematron.
As for your problems to run the second sample with node-schematron, it uses an XPath implementation that doesn't support the XPath 3.1 sort function it seems, node-schematron also fails to handle maps as intermediary results of a Schematron variable, so only stuffing all into one variable expression seems to do; two examples work:
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
<sch:ns prefix="map" uri="http://www.w3.org/2005/xpath-functions/map"/>
<sch:pattern>
<sch:rule context="root">
<sch:let name="failing-patients"
value="let $encounter-resources := entry/resource[resourceType = 'Encounter'],
$groups := map:merge(
$encounter-resources
!
map {
data(subject/id) : xs:dateTime(encounterDate)
},
map { 'duplicates' : 'combine' }
)
return map:keys($groups)[(current-dateTime() - max($groups(.))) gt xs:dayTimeDuration('P365D')]"/>
<sch:report
test="exists($failing-patients)">Patients <sch:value-of select="$failing-patients"/> with latest encounter more than a year ago.</sch:report>
</sch:rule>
</sch:pattern>
</sch:schema>
or
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
<sch:ns prefix="map" uri="http://www.w3.org/2005/xpath-functions/map"/>
<sch:pattern>
<sch:rule context="root">
<sch:let name="failing-patients"
value="let
$encounter-resources := entry/resource[resourceType = 'Encounter'],
$groups := fold-left(
$encounter-resources,
map{},
function($m, $e) {
map:put(
$m,
data($e/subject/id),
max((xs:dateTime($e/encounterDate), map:get($m, data($e/subject/id))))
)
})
return map:keys($groups)[(current-dateTime() - $groups(.)) gt xs:dayTimeDuration('P365D')]"/>
<sch:report test="exists($failing-patients)">Patients <sch:value-of
select="$failing-patients"/> with latest encounter more than a year
ago.</sch:report>
</sch:rule>
</sch:pattern>
</sch:schema>
If you need an assertion that fails then replace the sch:report with
<sch:assert
test="empty($failing-patients)">Patients <sch:value-of select="$failing-patients"/> with latest encounter more than a year ago.</sch:assert>
I am trying to use mapforce to generate an xslt 2.0 file. The mapping is adding 2 dayTimeDuration elements, doing so results in the following error;
No match for core.add(xs:dayTimeDuration, xs:dayTimeDuration). Check argument types.
Supported: +(xs:double, xs:double) -> xs:double
I thought that xslt 2.0 supported adding 2 dayTimeDurations. Is there a way of doing this using mapforce?
Cheers
Stew
Had almost the same problem, first tried to add functx-library but saw it creates absolute path in the generated xslt2-code, which isn't very good.
Well, turns out you can implement that function, but first you have to do some modifications...
Find your Mapforce installation directory, and MapForceLibraries -subdirectory. From that open the "core.mff", and find
<group name="math functions">
<component name="add" growable="true" growablebasename="value">
<sources>
<datapoint name="value1" type="xs:decimal"/>
<datapoint name="value2" type="xs:decimal"/>
</sources>
<targets>
<datapoint name="result" type="xs:decimal"/>
</targets>
As you can seem the "sources" and "targets" elements seems to define the in- and out data types. As it is, they have only implemented "add"-function for "xs:decimal". You can copy/paste this component, then rename it and give new in- out- data types, in your case they are both "xs:dayTimeDuration". Note that there are implementations for each supported language, but you can omit those that are not needed. Here's
what should work:
<component name="addDayTimeDuration" growable="true" growablebasename="value">
<sources>
<datapoint name="value1" type="xs:dayTimeDuration"/>
<datapoint name="value2" type="xs:dayTimeDuration"/>
</sources>
<targets>
<datapoint name="result" type="xs:dayTimeDuration"/>
</targets>
<implementations>
<implementation language="xslt">
<operator value="+"/>
</implementation>
<implementation language="xslt2">
<operator value="+"/>
</implementation>
<implementation language="builtin">
<function name="Core_Add"/>
</implementation>
</implementations>
<description>
<short>result = value1 + value2</short>
<long>Result is the dayTimeDuration value of adding value1 and value2.</long>
</description>
</component>
Your new function should now appear in the "math functions" and should be good to use.
After contacting Altova (the makers of MapForce);
While XPath 2 does offer a subtract-dayTimeDurations operation, this is not presently offered as a function inside MapForce.
I have problem in copying the output of a service response to the response message in BPEL .
The amount element has an attribute currency, How do I acheiev this ? All other copying seems to work fine, except copying an element to an attribute of another element.
The copy expression is below.
<copy>
<from variable="InvokePersistence_insert_OutputVariable"
part="ProBookingInitiationCollection" query="/ns3:ProBookingInitiationCollection/ns3:ProBookingInitiation/ns3:bookingDetail/ns3:isoCurrencyCd"/>
<to variable="outputVariable" part="payload"
query="/ns4:BookingConfirmation/ns4:amount/#ns4:currency"/>
</copy>
The excerpts from xsd is below
<xs:element name="amount">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Make sure that "outputVariable" output variable is properly initialised according to the schema and contains an attribute called "currency"
We have JAX-RPC style web service, with a complex type defined as follows:
<xs:complexType name = "SomeFault">
<xs:sequence>
<xs:element name = "errorMessages" type="some:ErrorMessageWSType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name = "ErrorMessageWSType">
<xs:restriction base = "xs:NMTOKEN">
<xs:enumeration value = "INVALID_1"/>
<xs:enumeration value = "INVALID_2"/>
<xs:enumeration value = "INVALID_3"/>
</xs:restriction>
</xs:simpleType>
We are running into Marshaling exception on the server side when the response/fault complex type has a single array type field.
weblogic.wsee.codec.CodecException: Failed to encode
com.bea.xml.XmlException: failed to find a suitable binding type for
use in marshalling object
"[Lnamespace.type.ErrorMessageWSType;#693767e9". using schema type:
t=SomeFault#http://namespace/SOME/v1 java
type:namespace.type.ErrorMessageWSType[]
If we change SomeFault, by adding another element to the complex type the error goes away.
<xs:complexType name = "SomeFault">
<xs:sequence>
<xs:element name = "errorMessages" type="some:ErrorMessageWSType" maxOccurs="unbounded" />
<xs:element name = "dummyString" type="xsd:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
Are we doing something wrong during the wsdlc code generation or is this a known issue?
A similar question is already posted at https://forums.oracle.com/forums/thread.jspa?messageID=4462906, but without any response, any pointers would be great.
Thanks.
Don't know if this solves the "why" part of the question, but you could try rewriting the sequence part like:
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="errorMessages" type="some:ErrorMessageWSType"/>
</xs:sequence>
OTOH, what might be the mechanism that lets the second case work, but not the first?
Might it be that the marshaller then has to figure out what xsd:string means before checking what some:ErrorMessageWSType means, and then has to wake up a resolver or something?
This line of thought leads to the second approach I would try, which would be to declare ErrorMessageWSType before SomeFault (and perhaps in another namespace, just to see if that fixes anything).
Just my (tired) two cents, and I guess that both of these approaches presume a bug of some sort in the marshaller, because I can't really see that anything in your example code isn't according to the XML schema definition.
I'm trying to consume a .Net web service of mine in a Flex Builder 3 project. The function's signature in the service is:
bool MyFunction(Enums.Channels var1, Enums.Payments.PayMethods var2)
I tried importing the WSDL with the wizard but when I tried to call the web service it results in an error stating
"Cannot marshall type "http://www.w3.org/2001/XMLSchema::EnumsChannel"
to simple type"
What kind of object do I need to create in Flex Builder 3 to pass into the webservice so that it will recognize it as the appropriate type? The wizard is not correctly creating the appropriate type. Here is the xsd for the enums.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://schemas.datacontract.org/2004/07/My.Shared" elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/My.Shared">
<xs:simpleType name="Enums.Channels">
<xs:restriction base="xs:string">
<xs:enumeration value="Web"/>
<xs:enumeration value="ContactCenter"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Enums.Channels" nillable="true" type="tns:Enums.Channels"/>
<xs:simpleType name="Enums.Payments.PayMethods">
<xs:restriction base="xs:string">
<xs:enumeration value="CreditCard"/>
<xs:enumeration value="PayPal"/>
<xs:enumeration value="eBillme"/>
<xs:enumeration value="BillMeLater"/>
<xs:enumeration value="TeleCheck"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Enums.Payments.PayMethods" nillable="true" type="tns:Enums.Payments.PayMethods"/>
</xs:schema>
I'd like to try to build my own objects to call the service myself (without the wizard).... created the mx:WebService and mx:Operation but not sure how to handle the enum parameters.
I suppose this is a bit similar to this question Flex, .NET Web Service and Numeric Enums but a bit reversed.
try this
<s:WebService id="myWS" wsdl="yourServicePath?WSDL" result="resultHandler(event)" fault="faultHandler(event)">
<s:operation name="MyFunction">
<s:request xmlns="">
<var1>{var1 value}</var1>
<var2>{var2 value}</var2>
</s:request>
</s:operation>
</s:WebService>
to call the webservice: type
myWS.MyFunction.send();