Chameleon: Why is a repeating comment truncated? - grammar

I'm having trouble with the transformation of an HL7 message. Its got an NTE segment with repeating fields of type string.
ex:
MSH|^~\&|HOST||TD-SYN||201207031000||ORU^R01|0017|P|2.3
PID|1||0001|
NTE|||Comment 1~Comment 2~Comment3
What happens after a graphical transformation is, NTE just takes Comment 1 and the rest of the repeating comments are ignored.
MSH|^~\&|HOST||TD-SYN||201207031000||ORU^R01|0017|P|2.3
PID|1||0001|
NTE|||Comment 1|
I tried setting the "Repeats" field of NTE segment's grammar to 10 but doesn't make a difference. Also, no script is manipulating that field of NTE, so I have no idea why it truncates it that way. Can someone tell me what's going on?

Glad you found it. Just as a general help, use sometimes the HAPI TestPanel to convert into XML, then you see very well how to loop over your HL7 elements. You then also know if you're using a correct HL7 structure.
In your example on the 3rd element in NTE <NTE.3>:
<?xml version="1.0" encoding="UTF-8"?>
<ORU_R01 xmlns="urn:hl7-org:v2xml">
<MSH>
<MSH.1>|</MSH.1>
<MSH.2>^~\&</MSH.2>
<MSH.3>
<HD.1>HOST</HD.1>
</MSH.3>
<MSH.5>
<HD.1>TD-SYN</HD.1>
</MSH.5>
<MSH.7>
<TS.1>201207031000</TS.1>
</MSH.7>
<MSH.9>
<CM_MSG.1>ORU</CM_MSG.1>
<CM_MSG.2>R01</CM_MSG.2>
</MSH.9>
<MSH.10>0017</MSH.10>
<MSH.11>
<PT.1>P</PT.1>
</MSH.11>
<MSH.12>2.3</MSH.12>
</MSH>
<ORU_R01.RESPONSE>
<ORU_R01.PATIENT>
<PID>
<PID.1>1</PID.1>
<PID.3>
<CX.1>0001</CX.1>
</PID.3>
</PID>
<NTE>
<NTE.3>Comment 1</NTE.3>
<NTE.3>Comment 2</NTE.3>
<NTE.3>Comment3</NTE.3>
</NTE>
</ORU_R01.PATIENT>
</ORU_R01.RESPONSE>
</ORU_R01>

I just found the answer from its documentation. It isn't actually truncated.
The default value of "value" is the first element in the repeatable field. Thus,
all I had to do is to access the repeating fields via field.repeat_field(index).value. :)

Related

save entity-find results and iterate throught it later

I'm doing a conditional entity-find and want to save the results somewhere to iterate through it later. I searched around and found 2 solutions. I'm using mySql btw.
1-create a temp table and insert results into it
2-saving results in a file (csv, ...)
now my question is:
1-which solution is preferable or maybe suggest another solution (common/trusted pattern)
2- how to do it? (for example I don't know how to create a table on the fly or drop it in moqui.Suggesting a resource/example source code etc. would be awesome)
thanks in advance
One possible approach would be to convert the list that your entity-find gives you to binary data and store it as a DbResourceFile using the moqui.resource.DbResource entities, and using the utilities from org.apache.commons.io etc.
EDIT - To expound in response to comment below, I was thinking along such lines as
<set field="fileData" from="yourList.toString().getBytes()" />
<service-call name="create#moqui.resource.DbResource" in-map="[filename:'ExampleListFrom01012019.bin', isFile:'N']" out-map="context" />
<service-call name="create#moqui.resource.DbResourceFile" in-map="context + [mimeType:'application/octet-stream', fileData:fileData]" />
Then bring it back after a find on the DBResource with something like
<set field="convertedBack" from="x.fileData.getBinaryStream()" type="NewList" />
I haven't tried this, and there are no near samples in the code that I know of.
This type of conversion between types is not best practice, but storing lists to iterate through them later is probably not either.
Perhaps it would help if you elaborated on your business requirement.

Is there a way to do string replacement/substitution in sql?

I have some records in a CMS that include HTML fragments with custom tags for a widget tool. The maker of the CMS has apparently updated their CMS without providing proper data conversion. Their widgets use keys for layout based on screen width such as block_lg, block_md, block_sm. The problem kicks in with the fact they used to have a block_xs and they have now shifted them all -- dropping the block_xs and instead placing a block_xl on the other end.
We don't really use these things, but their widget configurations do. What this means for us is the values for each key are identical. The problem occurs when the updated CMS code is looking for the 'block_xl' in any widget definition tags, it can't find it and errors out.
What I'm thinking then is that the new code will appear to 'ignore' the block_xs due to how it reads the tags. (and similarly, the old code will ignore block_xl) Since the values for each are identical, I need to basically read any widget definition and add a block_xl value to it matching the value of [any one of] the other width parameters.
Since the best place order-wise would be 'before' the block_lg value, it's probably easiest to do it as follows:
Replace any thing matching posix style regex matching /block_lg(="\d+,\d+")/ with: block_xl="$1" block_lg="$1"
Or whatever the equivalent of that would be.
Example of an existing CMS block with multiple widget definitions:
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="The Album" classes="highlight-bottom modish greenfont font52 fontlight"
enable_fullwidth="0" block_ids="127" lazyload="0"
block_lg="127,12," block_md="127,12," block_sm="127,12," block_xs="127,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
<!-- Image Block -->
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="What’s Your Favorite Cover Style?"
classes="zoo-widget-style2 modish grey font26 fontlight"
enable_fullwidth="0" block_ids="126" lazyload="0"
block_lg="126,12," block_md="126,12," block_sm="126,12," block_xs="126,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
What I would prefer to end up with from the above (adding block_xl):
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="The Album" classes="highlight-bottom modish greenfont font52 fontlight"
enable_fullwidth="0" block_ids="127" lazyload="0"
block_xl="127,12," block_lg="127,12," block_md="127,12," block_sm="127,12," block_xs="127,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
<!-- Image Block -->
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="What’s Your Favorite Cover Style?"
classes="zoo-widget-style2 modish grey font26 fontlight"
enable_fullwidth="0" block_ids="126" lazyload="0"
block_xl="126,12," block_lg="126,12," block_md="126,12," block_sm="126,12," block_xs="126,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
I know how to do it in php and if necessary, I will just replace it on my local DB and write an sql script to update the modified records, but the html blocks can be kind of big in some cases. It would be preferable, if it is possible, to make the substitutions right in the SQL but I'm not sure how to do it or if it's even possible to do.
And yes, there can be more than one instance of a widget in any given cms page or block. (i.e. there may be a need for more than one such substitutions with different local 'values' assigned to the block_lg)
If anyone can help me do it in SQL, it would be greatly appreciated.
for reference, the tables effected are called cms_page and cms_block, the name of the row in both cases is content
SW

Concat in xslt, unable to get an image from server

I am new to xslt coding, I am trying to fix an issue in existing piece of code. I got stuck up at a point
<fo:external-graphic content-width="150pt"
content-height="50pt"
src="url:{concat('${OA_MEDIA}/',$revised_last_name,',',DOCUMENT_BUYER_FIRST_NAME,'.gif')}" />
The above piece of code is trying to find a .gif file in OA_MEDIA directory. Till that part I can understand fine.
When I am placing a file name as "Eckert,Tim.gif" (excluding the quotes) my program isn't picking that file
In the above piece, I printed $revised_lastname and $document_buyer_first_name..It's coming as Tim and Eckert, but it's still not picking the file. If I am hardcoding a file name like below it's working fine
<fo:external-graphic content-width="150pt"
content-height="50pt"
src="url:{concat('${OA_MEDIA}/','Tim','.gif')}" />
How can I print what value is coming into the src in above piece of code so I can see what file is it trying to look in the $OA_MEDIA.
Any suggestions are appreciated.
Thanks!
Your first problem appears to be that in your constructed URI and your file name, you have put the given name and the family name in different orders: Tim,Eckert.gif vs Eckert,Tim.gif. Choose one.
If you still have problems after that, your next step is to confirm that your concatenation is producing the value you expect. I'd add a line like
<xsl:message>Generating fo:external graphic with URI <xsl:value-of
select="concat('url:',
'${OA_MEDIA}/',
$revised_last_name,
',',
DOCUMENT_BUYER_FIRST_NAME,
'.gif')"/></xsl:message>
And if that did not shed light on what was going wrong, I'd insert individual messages to display the current value of $revised_last_name and DOCUMENT_BUYER_FIRST_NAME.
More than that it's difficult to say, because your question does not provide a short, self-contained, complete example that allows readers to reproduce the problem you are trying to solve. There is good advice on asking effective questions in the SO help files and in Eric Raymond and Rick Moen's essay How to ask questions the smart way.

Avoid duplicates in the destination schema

I have a little problem. I want to map every detail line to one OrderInfo. The destination schema can not have any duplicate OrderInfo. All the detail lines should be in the destination orderInfo, but the SuppliersOrderNo and BuyersOrderNo should not be twice.
Any ideas how to do this, is it possible to use XSL or inline script?
<inv:OrderInfo>
<inv:SuppliersOrderNo>123456</inv:SuppliersOrderNo>
<inv:BuyersOrderNo>6789</inv:BuyersOrderNo>
<inv:DetailLines>
<inv:DetailLine>
<inv:InvoiceDetailLineNo>1</inv:InvoiceDetailLineNo>
<inv:Item>
<inv:SuppliersArticleNo>article2</inv:SuppliersArticleNo>
<inv:SuppliersDescription>BestArticle</inv:SuppliersDescription>
</inv:Item>
</inv:DetailLine>
<inv:DetailLine>
<inv:InvoiceDetailLineNo>2</inv:InvoiceDetailLineNo>
<inv:Item>
<inv:SuppliersArticleNo>article3</inv:SuppliersArticleNo>
<inv:SuppliersDescription>AlmostBestArticle</inv:SuppliersDescription>
</inv:Item>
</inv:DetailLine>
</inv:DetailLines>
</inv:OrderInfo>
<inv:OrderInfo>
<inv:SuppliersOrderNo>123456</inv:SuppliersOrderNo>
<inv:BuyersOrderNo>6789</inv:BuyersOrderNo>
<inv:DetailLines>
<inv:DetailLine>
<inv:InvoiceDetailLineNo>1</inv:InvoiceDetailLineNo>
<inv:Item>
<inv:SuppliersArticleNo>article1337</inv:SuppliersArticleNo>
<inv:SuppliersDescription>WOW</inv:SuppliersDescription>
</inv:Item>
</inv:DetailLine>
</inv:DetailLines>
</inv:OrderInfo>
If you want to do this purely in XSLT, you'll have to use Muenchian gruoping. I wrote a blog that links to some other blogs on how to do this in BizTalk a little while back: https://blog.tallan.com/2014/12/09/muenchian-grouping-in-biztalk-while-keeping-mapper-functionality/
To summarize the blog: if you pursue this, you'll need a map that's completely custom XSLT somewhere, but you could put it into a custom pipeline component if you still want to be able to use "regular" maps functionality without any other caveats (in my blog I describe a method of doing that in a pipeline component so that a "regular" BizTalk map can still be used on the preprocessed output). There are lots of resources on Muenchian grouping out there (including on StackOverflow), so I'm not rehashing all of that in this answer.
You could also try to serialize the message in a C# component and use some LINQ methods to group/sort/order/etc, or if you're inserting the content into SQL at some point you could do it in SQL (which would be able to handle this kind of task more naturally).

Openrefine not working as expected

I'm very new to OpenRefine, so please bear with me if i have made a simple mistake.
I'm parsing a HTML website to gather some date.
Everything went fine with fetching the individual pages, but now the parsing of the HTML fails.
I'm creating a new column, based on the one holding all the page's HTML. I'm trying to get to the data in a specific DIV[20].
In the"create column based on this column" window it gives me a preview when using value.parseHtml().select("DIV")[20] , which results in exactly what i need... executing it gives me nothing but blank cells.
it even tells me that it is "filling 0 rows with grel:value.parseHtml().select("DIV")[20]"
Any clue what i'm doing wrong here?
You just need to finalize with .toString() to output the JSON.org object AS a string.
This is explained on our wiki here: https://github.com/OpenRefine/OpenRefine/wiki/StrippingHTML#extract-html-attributes-text-links-with-integrated-grel-commands
I also updated the select() function with that example: https://github.com/OpenRefine/OpenRefine/wiki/GREL-Other-Functions#selectelement-e-string-s