If an element in an SD has a type.profile, from where should the snapshot draw element descriptive information?
Given:
<StructureDefinition>
...
<name value="Acme-Patient" />
<baseDefininition value="http://hl7.org/fhir/StructureDefinition/Patient" />
...
<differential>
<element>
<path value="identifier" />
<type>
<code value="Identifier" />
<profile value="http://example.com/fhir/SD/id-qualified" />
...
</StructureDefinition>
HL7's Patient http://hl7.org/fhir/StructureDefinition/Patient has short:"An identifier for this patient" for Patient.identifier.
Example.com's id-qualified Identifier type has short: "An identifier qualified with a required system."
What should the Acme-Patient snapshot element for Patient.identifier have for its short value?
Before answering, consider that extensions are the more common use case here. The type.profile defines the extension. If from the baseDefinition, all extensions will have short "Additional Content defined by implementations". However, in the above example, the type is much more generic than the base's short.
Related
I am debatching an incoming xml messages in BizTalk receive pipeline using an envelope schema. The debatching works well for any xml that contains the sub message I am trying to debatch but fails if the message does not contain any sub message.
I have set the "min occurs" to 0 and nillable = true in the schema for the elements that are in the xpath for debatching. In the sample below the "entry" and "resource" elements have min occurs set to 0, which I thought would let the debatching function work when there is nothing to be debatched.
Here is the annotation for the envelope schema.
<xs:annotation>
<xs:appinfo>
<schemaInfo xmlns="http://schemas.microsoft.com/BizTalk/2003" is_envelope="yes"/>
</xs:appinfo>
</xs:annotation>
<xs:element name="Bundle">
<xs:annotation>
<xs:appinfo>
<recordInfo xmlns="http://schemas.microsoft.com/BizTalk/2003" body_xpath="/*[local-name()='Bundle' and namespace-uri()='']/*[local-name()='entry' and namespace-uri()='']/*[local-name()='resource' and namespace-uri()='']"/>
</xs:appinfo>
</xs:annotation>
Example message with no messages to debatch
<Bundle >
<type value="searchset"/>
<total value="0"/>
</Bundle>
Example of xpath for debatching when sub messages are present.
<Bundle >
<type value="searchset"/>
<total value="46"/>
<entry>
<resource>
<Encounter>
Any message that contains the entry/resource/encounters element debatches successfully, but the messages that do not contain the "entry" element ( has no messages to debatch) throw the error below.
Reason: This Disassembler cannot retrieve body nodes using this XPath: "/[local-name()='Bundle' and namespace-uri()='']/[local-name()='entry' and namespace-uri()='']/[local-name()='resource' and namespace-uri()='']".
/[local-name()='Bundle' and namespace-uri()='']/[local-name()='entry' and namespace-uri()='']/[local-name()='resource' and namespace-uri()='']
I would expect the messages with nothing to debatch to simply "disappear", but instead I end up with an error in group hub. Any ideas or suggestion on how to get rid of this error would be greatly appreciated.
You can use below body_xpath to extract only the 'Bundle' with 'entry' records
body_xpath="/*[local-name()='Bundle' and namespace-uri()=''][*[local-name()='entry' and namespace-uri()=''][count(*)>0]]/*[local-name()='entry' and namespace-uri()='']/*[local-name()='resource' and namespace-uri()='']"
or
body_xpath="/*[local-name()='Bundle' and namespace-uri()=''][*[local-name()='entry' and namespace-uri()=''][count(*)>0]]/*[local-name()='entry' and namespace-uri()='']/*[local-name()='resource' and namespace-uri()='']"
That is because you are pointing the body at the resource node, which does not even exists when there is no message to debatch. You need to be pointing at the a node that always exists in the envelope under which the body messages occur.
What you probably need is the following for emtpy
<Bundle >
<type value="searchset"/>
<total value="0"/>
<entries/>
</Bundle>
and the following for messages.
<Bundle >
<type value="searchset"/>
<total value="46"/>
<entries>
<entry>
<resource>
<Encounter>
And point your body_xpath at entries.
Is there a way to use mod_lcr with originate command?
I want to originate a call and have mod_lcr decide which gateway should be used based on lcr rules (cost, reliability, etc).
When mod_lcr is used in the dialplan it will populate a variable ${lcr_auto_route} with the dialstring. How can I use the same logic with originate?
Thank you.
Here is how I did it.
I connect to freeswitch via ESL and execute the command
lcr 1716 default as xml
where 1716 is the digit sequence and default is the profile name (you can replace default with your own profile name)
Note 'as xml' will return an XML response. The response looks like this:
<result>
<row id="1">
<prefix>1716</prefix>
<carrier_name>carrier1</carrier_name>
<rate>0.15000</rate>
<codec></codec>
<cid></cid>
<limit></limit>
<dialstring>[lcr_carrier=carrier1,lcr_rate=0.15000]sofia/gateway/carrier1/1716</dialstring>
<event>
<headers>
<Event-Name>REQUEST_PARAMS</Event-Name>
<Core-UUID>151c590b-cce8-4eb3-b3ae-f48bad397870</Core-UUID>
<FreeSWITCH-Hostname>freeswitch</FreeSWITCH-Hostname>
<FreeSWITCH-Switchname>freeswitch</FreeSWITCH-Switchname>
<FreeSWITCH-IPv4>172.16.124.130</FreeSWITCH-IPv4>
<FreeSWITCH-IPv6>%3A%3A1</FreeSWITCH-IPv6>
<Event-Date-Local>2018-02-20%2007%3A33%3A42</Event-Date-Local>
<Event-Date-GMT>Tue,%2020%20Feb%202018%2006%3A33%3A42%20GMT</Event-Date-GMT>
<Event-Date-Timestamp>1519108422660002</Event-Date-Timestamp>
<Event-Calling-File>mod_lcr.c</Event-Calling-File>
<Event-Calling-Function>route_add_callback</Event-Calling-Function>
<Event-Calling-Line-Number>633</Event-Calling-Line-Number>
<Event-Sequence>786</Event-Sequence>
<lcr_digits>1716</lcr_digits>
<lcr_carrier_name>carrier1</lcr_carrier_name>
<lcr_rate_field>0.15000</lcr_rate_field>
<lcr_gw_prefix>sofia/gateway/carrier1/</lcr_gw_prefix>
<lcr_lead_strip>0</lcr_lead_strip>
<lcr_trail_strip>0</lcr_trail_strip>
</headers>
</event>
</row>
<row id="2">
<prefix>1</prefix>
<carrier_name>carrier2</carrier_name>
<rate>0.12000</rate>
<codec></codec>
<cid></cid>
<limit></limit>
<dialstring>[lcr_carrier=carrier2,lcr_rate=0.12000]sofia/external/0716#proxy.carrier2.net:5060</dialstring>
<event>
<headers>
<Event-Name>REQUEST_PARAMS</Event-Name>
<Core-UUID>151c590b-cce8-4eb3-b3ae-f48bad397870</Core-UUID>
<FreeSWITCH-Hostname>freeswitch</FreeSWITCH-Hostname>
<FreeSWITCH-Switchname>freeswitch</FreeSWITCH-Switchname>
<FreeSWITCH-IPv4>172.16.124.130</FreeSWITCH-IPv4>
<FreeSWITCH-IPv6>%3A%3A1</FreeSWITCH-IPv6>
<Event-Date-Local>2018-02-20%2007%3A33%3A42</Event-Date-Local>
<Event-Date-GMT>Tue,%2020%20Feb%202018%2006%3A33%3A42%20GMT</Event-Date-GMT>
<Event-Date-Timestamp>1519108422660002</Event-Date-Timestamp>
<Event-Calling-File>mod_lcr.c</Event-Calling-File>
<Event-Calling-Function>route_add_callback</Event-Calling-Function>
<Event-Calling-Line-Number>633</Event-Calling-Line-Number>
<Event-Sequence>787</Event-Sequence>
<lcr_digits>1</lcr_digits>
<lcr_carrier_name>carrier2</lcr_carrier_name>
<lcr_rate_field>0.12000</lcr_rate_field>
<lcr_gw_prefix>sofia/external/</lcr_gw_prefix>
<lcr_gw_suffix>%40proxy.carrier2.net%3A5060</lcr_gw_suffix>
<lcr_lead_strip>1</lcr_lead_strip>
<lcr_trail_strip>0</lcr_trail_strip>
<lcr_prefix>0</lcr_prefix>
</headers>
</event>
</row>
</result>
Then I parse the XML and grab the dialstring which is in this case
<dialstring>[lcr_carrier=carrier1,lcr_rate=0.15000]sofia/gateway/carrier1/1716</dialstring>
Then I use the dialstring (with some extra variables) in my originate command.
I have a scenario where I am filtering a xml payload based on a xpath value.
<int:channel id="documentReceiptFilterChannel" />
<int:chain input-channel="documentReceiptFilterChannel" output-channel="nullChannel">
<!-- Filter to discard message if <statusCode> value is 'EMLOK' -->
<int-xml:xpath-filter match-type="regex" match-value="^(?!\bEMLOK\b).*$" discard-channel="nullChannel">
<int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
</int-xml:xpath-filter>
<int:service-activator expression="#opsLogger.logError('TransactionId=' + headers.correlationId, ' Msg=' + #opsExceptionUtils.createOPSExceptionInstance(#root))" />
</int:chain>
Following is the payload:
<?xml version="1.0" encoding="UTF-8"?>
<GetDocumentReceiptReply xmlns="http://example.org"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<mergeReceiptDeliveryStatus>
<statusCode>EMLOK</statusCode>
</mergeReceiptDeliveryStatus>
</GetDocumentReceiptReply>
My requirement is that when <statusCode>EMLOK</statusCode> element is available, discard the message and hence nullChannel is mentioned as discard-channel.
But then there is any other value, proceed to the next step in the chain and do the error logging - <int:service-activator expression="#opsLogger.logError().
The above setup works fine as long as <statusCode> element is present in the payload. But doesn't work on the following situations:
<statusCode></statusCode>
<statusCode/>
<statusCode> is missing
Or any other xml payload
To get rid of namespace issues, the xpath expression is formed as <int-xml:xpath-expression expression="//*[local-name()='statusCode']" />. The xpath value is matched against regex expression match-type="regex" match-value="^(?!\bEMLOK\b).*$" (For value != 'EMLOK').
What happens when <int-xml:xpath-expression /> evaluation fails?
My only requirement is that if <statusCode>EMLOK</statusCode> is present, discard the message, else for all other, log an error in the log file. (And not to throw an exception that will propagate to error-channel).
You could write a custom subclass of AbstractXPathMessageSelector and delegate to a BooleanTestXPathMessageSelector and a RegexTestXPathMessageSelector, or simply use 2 filters...
<int:chain input-channel="documentReceiptFilterChannel" output-channel="errors">
<int-xml:xpath-filter discard-channel="errors">
<int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
</int-xml:xpath-filter>
<int-xml:xpath-filter match-type="regex" match-value="^(?!\bEMLOK\b).*$">
<int-xml:xpath-expression expression="//*[local-name()='statusCode']" />
</int-xml:xpath-filter>
</int:chain>
<int:service-activator
expression="#opsLogger.logError('TransactionId=' + headers.correlationId, ' Msg=' + #opsExceptionUtils.createOPSExceptionInstance(#root))" />
Notice that you don't need to discard to nullChannel - just omitting the discard channel will cause discards. Messages that pass the second filter go to the chain's output channel.
The custom selector would be a little more efficient because only one conversion to node is needed.
How do i find a text() node in XmlConfig and use it to remove the parent nodeset. All the examples I have seen just find and remove the 'found' node not the parent nodes.
My understanding is that this Xpath finds the matching node via verify path and ElementPath is the path of the nodes to remove. However Its not working at all.
Is text() supported?, I have tried [[*='ATrigger'[]], [[].='ATrigger'[]] but still no luck.
<util:XmlConfig Id="RemoveATriggerCompletely" File="[#QuartzXmlJob]" Sequence="104" Action="delete" On ="install" Node="element"
ElementPath="//job-scheduling-data/schedule/"
VerifyPath="//job-scheduling-data/schedule/trigger/cron/name[\[]text()='ATrigger'[\]]"/>
Given the following XML
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<schedule>
<trigger>
<cron>
<name>ATrigger</name>
<group>default</group>
<description>Every 2 minutes</description>
<job-name>ATriggerJob</job-name>
<job-group>defaultGroup</job-group>
<misfire-instruction>SmartPolicy</misfire-instruction>
<!-- every 5mins -->
<cron-expression>2 * * * * ?</cron-expression>
</cron>
</trigger>
<trigger>
<cron>
<name>BTrigger</name>
<group>default</group>
<description>Every 2 minutes</description>
<job-name>BTriggerJob</job-name>
<job-group>defaultGroup</job-group>
<misfire-instruction>SmartPolicy</misfire-instruction>
<!-- every 5mins -->
<cron-expression>2 * * * * ?</cron-expression>
</cron>
</trigger>
The output i require is
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<schedule>
<trigger>
<cron>
<name>BTrigger</name>
<group>default</group>
<description>Every 2 minutes</description>
<job-name>BTriggerJob</job-name>
<job-group>defaultGroup</job-group>
<misfire-instruction>SmartPolicy</misfire-instruction>
<!-- every 5mins -->
<cron-expression>2 * * * * ?</cron-expression>
</cron>
</trigger>
I have been banging my head against a wall for hours now so any help whatsoever is very much appreciated.
I'm not familiar with that "XmlConfig" task.
But I see two issues.
You need to alias the namespace and use that alias for the xpath "select".
I show the XmlPeek version below. Note I use "peanut", you can use any alias name you want.
Note the query now has "peanut:" in all the element names.
<!-- you do not need a namespace for this example, but I left it in for future reference -->
<XmlPeek Namespaces="<Namespace Prefix='peanut' Uri='http://quartznet.sourceforge.net/JobSchedulingData'/>"
XmlInputPath=".\Parameters.xml"
Query="//peanut:job-scheduling-data/peanut:schedule/peanut:trigger/peanut:cron/peanut:name[text()='ATrigger']/../..">
<Output TaskParameter="Result" ItemName="Peeked" />
</XmlPeek>
Note my "../.."
Once you find the correct element, finding its parent(s) is simple as the ".." notation.
You'll need to figure out how to add the namespace and alias to your Task (XmlConfig)
APPEND:
http://sourceforge.net/p/wix/bugs/2384/
Hmmm...dealing with a namespace isn't trivial. I think you're having a similar issue to what is reported there.
APPEND:
"Inline" Namespacing ... (Yuck)
<XmlPeek
XmlInputPath=".\Parameters.xml"
Query="//*[local-name()='job-scheduling-data' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']/*[local-name()='schedule' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']/*[local-name()='trigger' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']/*[local-name()='cron' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']/*[local-name()='name' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData'][text()='ATrigger']/../..">
<Output TaskParameter="Result" ItemName="Peeked" />
</XmlPeek>
Aka, try this Xpath:
"//*[local-name()='job-scheduling-data' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']/*[local-name()='schedule' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']/*[local-name()='trigger' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']/*[local-name()='cron' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData']/*[local-name()='name' and namespace-uri()='http://quartznet.sourceforge.net/JobSchedulingData'][text()='ATrigger']/../.."
I am using lxml library in python and I am working with xpath.I have a an xml file example as follows:
<Root>
<Child1 name="child1">
<Child2 name="child2" />
</Child1>
<Child3 name="child3">
<Child4 name="child4" />
</Child3>
<Child5 name="child5" />
</Root>
i need to know if there is a way to get all children at once like child1,child2,child3,child4 at once... currently I am able to get only child1, child3, child5 using root.xpath('node()')