Sending multiple emails from within Orbeon Forms - orbeon

On Orbeon Forms 4.8, I've rebuilt email-form.xpl so that it constructs different emails depending on various conditions in the form. That works nicely, and it's even embedding form information in the emails it creates. I've got to the point where I have created a nicely structured set of structures, as expected by the Orbeon Email processor. They are all wrapped up in a tag, so I have something like ....
When it comes to actually calling the email processor, I need to work through that XML structure calling the email processor for one message at a time. The code below is what I have to do this and I can see from the debug that it is receiving my messages correctly, but once I check inside the processor all of the XML tags have been stripped away, and the email processor won't accept the input (which I know would only send the first message if it worked at all) because it says it is an incomplete content model.
<p:processor name="oxf:pipeline">
<p:input
name="config"
href="#messages"
transform="oxf:unsafe-xslt"
debug="LOOPING THROUGH EMAIL MESSAGES - MESSAGES">
<p:config xsl:version="2.0">
<p:param type="input" name="messages"/>
<xsl:message>
XXXXX
<xsl:value-of select="messages/message"/>
XXXXX
</xsl:message>
<xsl:for-each select="/*/message">
<p:processor name="oxf:email">
<p:input name="data">
<message>
<xsl:value-of select="messages/message"/>
</message>
</p:input>
</p:processor>
</xsl:for-each>
</p:config>
</p:input>
</p:processor>
Clearly I did something wrong, but I don't see what it was.

To print the XML via XSLT, use <xsl:copy-of> instead of <xsl:value-of>. The latter always takes the string value of the XML, which only looks at the text nodes. The former makes a copy of the XML tree.
The email processor can only send one email at a time. So What's needed is iterating over the <message> elements you have created via XSLT. The iteration must be done in XPL, so you must use <p:for-each>.

Related

When I use send_keys Chrome cant receive all tags (XML)

I have a textbox and I'm using find_element command and send_keys to send XML but the problem is, when I send XML, Chrome doesn't receive all the tags as if it were very fast to receive and just missed the letters.
#browser.find_element(:xpath,'/html/body/form/textarea').send_keys(#xml)
#browser.find_element(:xpath,'//*[#id="BotaoEnviar"]').click
Example XML (taken from comment):
<Xml>
<Id>123456</Id>
<Card>1234567890</Card>
<Value>15000</Value>
</Xml>
error
<Xml>
<Id>123456</Id>
<Card>1234567890</crtao>
<Value>15000</vaor>
</Xml>

xpath expression to select specific xml nodes that are available in a file

I was trying to find the out a way for my strange problem.
How to write an xpath to select specific xml nodes that are available in another text file.
For Instance,
<xsl:for-each select="SUBSCRIBER_PROFILE_LIST/SUBSCRIBER_PROFILE_INFO[GROUP_NAME eq (group name list in a text file as input)]">
For example,
<xsl:for-each select="SUBSCRIBER_PROFILE_LIST/SUBSCRIBER_PROFILE_INFO[GROUP_NAME eq collection('select_nodes.txt')]">
select_nodes.txt contains list of string that can be selected only
For example
ABC
IJK
<SUBSCRIBER>
<MSISDN>123456</MSISDN>
<SUBSCRIBER_PROFILE_LIST>
<SUBSCRIBER_PROFILE_INFO>
<PROFILE_MSISDN>12345</PROFILE_MSISDN>
<GROUP_NAME>ABC</GROUP_NAME>
<GROUP_ID>18</GROUP_ID>
</SUBSCRIBER_PROFILE_INFO>
<SUBSCRIBER_PROFILE_INFO>
<PROFILE_MSISDN>456778</PROFILE_MSISDN>
<GROUP_NAME>DEF</GROUP_NAME>
<GROUP_ID>100</GROUP_ID>
</SUBSCRIBER_PROFILE_INFO>
<SUBSCRIBER_PROFILE_INFO>
<PROFILE_MSISDN>78876</PROFILE_MSISDN>
<GROUP_NAME>IJK</GROUP_NAME>
<GROUP_ID>3</GROUP_ID>
</SUBSCRIBER_PROFILE_INFO>
</SUBSCRIBER>
XSLT2 has limited functionality for parsing arbitrary text files. I would suggest:
Make the select_nodes.txt an XML file and load it using the doc() function:
<xsl:variable name="group_names" as="xs:string *"
select="doc('select_nodes.xml')/groups/group"/>
with select_nodes.xml looking like this:
<?xml version="1.0" encoding="UTF-8"?>
<groups>
<group>ABC</group>
<group>IJK</group>
</groups>
Pass the group names as a stylesheet parameter. (How you do this depends on which XSLT engine you're using and whether it's through the command line or an API.) If it's through an API, then you may be able to pass the values in directly as xs:string-typed objects. Otherwise you'll have to parse the parameter:
<xsl:param name="group_names_param"/>
<!-- Assuming the input string is a whitespace-separated list of names -->
<xsl:variable name="group_names" as="xs:string *"
select="tokenize($group_names_param, '\s+')"/>
In either case your for-each expression would then look like this:
<xsl:for-each select="
SUBSCRIBER_PROFILE_LIST/SUBSCRIBER_PROFILE_INFO[GROUP_NAME = $group_names]">
<!-- Do something -->
</xsl:for-each>

xslt how to read the document-node()

I have a xml file in which one of the element has the CDATA as the value. I put the CDATA value into a variable which I can see is value type of document-node(1) when i debug my code from oXygen. How do I iterate the document-node()?
copy can give me a new xml file. but what I need is not a new file. I only need to read certain nodes and generate a report based on the values on those nodes. so I directly copy the CDATA to my variable and thought I can manipulate it.
I tried to use substring to read the variable things but failed.
I tried to use document(variable) to open the variable but Oxygen give me the debug-error of FODC0002:I/O error reported by xml parser processing file.
here the file is my variable which looks like a xml file
I did google search for the error but only got bench of non-closed questions like Oxygen throw I/O error when use document().
Would anybody let me know what's going wrong? or give me a better solution?
I also tried parse-xml() but I got the following error from Saxon:
F[Saxon-EE9.5.1.5] the processing instruction target matching "[xX][mM][lL]" is not allowed
F[Saxon-EE9.5.1.5] FODC0006: First argument to parse-xml() is not a well formed and namespace-well-formed XML document.
my code to use parse-xml is as below:
<xsl:template match="data"
<xsl:for-each select="parse-xml(root/outsideData)//nodeLevel1/nodeLevel2">
Could anyone give me a sample about how to use parse-xml()? I did google search but didn't find useful samples.
Thanks very much!
A piece of my data is like the following:
<root>
<outsideData id="123">
<child1 key="124375438"/>
<![CDATA[ <?xml version=1.0 encoding="UTF-8"?><insideData xmlns:xlink="http://www.w3.org/1999/xlink">
<nodeLevel1>
<nodeLevel21>packing</nodeLevel21>
<nodeLevel22 ref="12343-454/560" xlink:href="URN:X-MN:DD%3FM=B888%26SDC=A%26CH=79% .../>
</nodeLevel1>
]]>
</outsideData>
</root>
I want to get the inside CDATA <nodeLevel22> #ref and #xlink which will get DD-FM-B888-26-79
My variables are:
<xsl:for-each select="/root/outsideData">
<xsl:variable name="insideData">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:variable>
<xsl:variable name="Data">
<xsl:value-of
select="normalize-space(substring-after($insideData,'?>'))"
disable-output-escaping="yes"/>
</xsl:variable>
</xsl:foreach>
From the debug I can see that the variable insideData and Data are both value type of document-node(1)
Martin's solution works for me very well :)
But I'm still wondering why the following doesn't work:
<xsl:variable name="insideData">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:variable>
<ref>
<xsl:value-of select="substring-before(substring-after($insideData, '<nodeLevel22 ref'),>/>')"/>
</ref>
Here I got empty <ref/>
If you do <xsl:variable name="varName"><xsl:value-of select="..."/><xsl:variable> then you are creating a temporary document fragment that contains a single text with the string contents of the item(s) selected in the value-of. That does not make sense in most cases, doing <xsl:variable name="varName" select="..."/> is usually sufficient.
As for parsing the contents of the outsideData element with parse-xml, there is indeed not only the escaped XML document inside that element but white space as well, thus if you try to parse the contents as XML you get that error as white space before the XML declaration is not allowed. The whole approach of stuffing the XML into a CDATA section with an element with mixed contents is flawed in my view, if you want to store escaped XML into a CDATA then you should make sure that you use a single element that contains nothing but the CDATA section which then only contains the XML markup with no leading white space.
If you can't change the creation of the input data then you will need to make sure you pass in only that part of the string contents of the element to parse-xml that is a well-formed XML document, so you need some way to strip the white space before the XML declaration doing e.g.
<xsl:for-each select="/root/outsideData">
<xsl:variable name="xml-string" select="replace(., '^\s+', '')"/>
<xsl:variable name="xml-doc" select="parse-xml($xml-string)"/>
<!-- now output data e.g. -->
<xsl:value-of select="$xml-doc//nodeLevel1/nodeLevel22/#ref"/>
...
</xsl:for-each>
Untested but should show the right direction as far as trying to use parse-xml.

how to decode base64Binary-to-string in xslt

Hi I am trying to convert my Base64 data to string in xslt but unable to do so.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/">
<xsl:template match="Data">
<xsl:element name="fos1">
<xsl:value-of select="(saxon:base64Binary-to-string(
xs:base64Binary("Data"),
"UTF8"))"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I have one xml file also where i have stored base64 data the looks like below code
<?xml version="1.0" encoding="UTF-8"?>
<Data>e1xydGYxXGZiaWRpc1xhbnNpXGFuc2ljcGcxMjUyXGRlZmYwXGRlZmxhbmcxMDMxXGRlZmxhbmdmZTEwMzFcZGVmdGFiNzA4e1xmb250dGJse1xmMFxmc3dpc3NcZnBycTJcZmNoYXJzZXQwIFZlcmRhbmE7fX0NClx2aWV3a2luZDRcdWMxXHBhcmRcbHRycGFyXGxhbmcyMDU3XGJcZjBcZnMyMCBGYXJlIFJ1bGVzXHBhcg0KXGIwXHBhcg0KXHBhcg0KXGIgUmVib29raW5nc1xwYXINClxwYXJkXGx0cnBhclxxalxiMCBCb29raW5nIGNoYW5nZXMgYWxsb3dlZCwgdXAgdG8gMzAgbWludXRlcyBwcmlvciB0byBkZXBhcnR1cmUsIGZvciBhIGZlZSBvZiBcYiBFVVIgNjAgLyBDSEYgNzkgLyBHQlAgNTQgLyBVU0QgODMgLyBDWksgMTY4MCAvIFNFSyA2MDAgLyBOT0sgNDkyIC8gUExOIDI3NiAvIEhVRiAxOTgwMFxiMCAgcGVyIHBlcnNvbiBhbmQgbGVnLCB3aGVyZSBhcHBsaWNhYmxlIHBsdXMgZGlmZmVyZW5jZSB0byBhY3R1YWwgZmxpZ2h0IGZhcmUuIENoYW5nZSBvZiB0YXJpZmYgb25seSBhbGxvd2VkIGludG8gbmV4dCBoaWdoZXIgY2F0ZWdvcnkgaWYgaW5pdGlhbCB0YXJpZmYgbm90IGF2YWlsYWJsZS4gSUYgVEhFIE5FVyBGQVJFIElTIExPV0VSIFRIQU4gVEhFIE9SR0lOQUwgT05FLCBOTyBSRUZVTkQgV0lMTCBCRSBHUkFOVEVELlxwYXINClxwYXINClxwYXJkXGx0cnBhclxiIENhbmNlbGxhdGlvbnNccGFyDQpcYjAgQ2FuY2VsbGF0aW9ucyBhcmUgbm90IGFsbG93ZWQuIEZhcmUgaXMgbm9uIHJlZnVuZGFibGUuIElOIENBU0UgT0YgTk9TSE9XLCBQQVggTVVTVCBQVVJDSEFTRSBBTiBFTlRJUkVMWSBORVcgVElDS0VUIC8gT1JJR0lOQUwgUEFJRCBBTU9VTlQgV0lMTCBOT1QgQkUgUkVGVU5ERUQvQ1JFRElURUQuXHBhcg0KXHBhcg0KXGIgTmFtZSBDaGFuZ2VzXHBhcg0KXGIwIE5hbWUgY2hhbmdlcyBhbGxvd2VkLCB1cCB0byAzMCBtaW51dGVzIHByaW9yIHRvIGRlcGFydHVyZSwgZm9yIGEgZmVlIG9mIFxiIEVVUiA2MCAvIENIRiA3OSAvIEdCUCA1NCAvIFVTRCA4MyAvIENaSyAxNjgwIC8gU0VLIDYwMCAvIE5PSyA0OTIgLyBQTE4gMjc2IC8gSFVGIDE5ODAwIFxiMCBwZXIgcGVyc29uIGFuZCBib29raW5nLCB3aGVyZSBhcHBsaWNhYmxlIHBsdXMgZGlmZmVyZW5jZSB0byBhY3R1YWwgZmxpZ2h0IGZhcmUuXHBhcg0KXHBhcg0KXGIgQ2hlY2tlZCBMdWdnYWdlXHBhcg0KXGIwIENoZWNrZWQgbHVnZ2FnZSBvcHRpb25hbCwgc3RhbmRhcmQgYWRkaXRpb25hbCBjb3N0cyBhcHBseS5ccGFyDQpcYiBBVFROISBTbWFydDpcYjAgIE9uZSBwaWVjZSBvZiBjaGVja2VkIGx1Z2dhZ2UgaXMgYXV0b21hdGljYWxseSBpbmNsdWRlZCBwZXIgcGVyc29uICh0b3RhbCB3ZWlnaHQgMjMga2cpLCBmb3IgZnVydGhlciBwaWVjZXMgYW5kIGV4Y2VzcyBsdWdnYWdlLCBzdGFuZGFyZCBhZGRpdGlvbmFsIGNvc3RzIGFwcGx5LlxwYXINClxwYXINClxiIFNlYXRpbmdccGFyDQpcYjAgT3B0aW9uYWwsIHN0YW5kYXJkIGFkZGl0aW9uYWwgY29zdHMgYXBwbHkuXHBhcg0KXGIgQVRUTiEgU21hcnQ6IFxiMCBTZWF0IHJlc2VydmF0aW9uIGlzIGluY2x1ZGVkIHBlciBQZXJzb24sIGFsc28gbW9yZSBsZWdyb29tIHNlYXQgKGlmIGF2YWlsYWJsZSlcYlxwYXINClxiMFxwYXINClxiIE1pbGVzXHBhcg0KXGIwIEluY2x1ZGluZyBtaWxlc1xwYXINClxwYXINClxiIE1lYWxccGFyDQpcYjAgTm90IGluY2x1ZGVkXHBhcg0KXGIgQVRUTiEgU21hcnQ6IFxiMCBTbmFjayBhbmQgZHJpbmsgaW5jbHVkZWRccGFyDQpccGFyDQpccGFyDQpcYiBBVFROISEgRm9yIEJsaW5kIEJvb2tpbmcgRmFyZXMgYW5kIEJvb21lcmFuZyBSZXdhcmQgZmxpZ2h0cyB0aGUgcGFydGljdWxhciBjb25kaXRpb25zIGFjY29yZGluZyB0byBHZXJtYW53aW5ncyBHQ0MgYXBwbHkuXHBhcg0KXHBhcg0KfQ0K</Data>
The call xs:base64Binary("Data") tries to create a base-64 value from the character string "Data", which is not a legal base-64 string. So you should be getting an error message saying roughly that. Hmm. You didn't mention an error message; you didn't explain what exactly you mean by "unable to do so". Next time, provide more information, ok?
If you want to apply the function to the string value of the Data element, bear in mind that you are making the call in an expression located in a template which matches that element. You almost certainly want to replace the call in the current expression with something like xs:base64Binary(.).

Umbraco 4 Document Type not showing on page

I am a newbie with Umbraco so please excuse if I am missing something obvious. I have trawled the internet, but I can't find a solution to my problem.
I am mainly using the Umbraco.TV videos to guide me through this, and in particularly, this one: http://umbraco.com/help-and-support/video-tutorials/umbraco-fundamentals/datatypes/using-content-and-media-pickers/TVPlayer.
The others videos and tutorials successfully got me through setting up a responsive nav and sub-nav, but on this issue, I'm stuck.
I am building a site which requires multiple CTAs. The text for these need to be entered by persons who have no coding experience so I've set up Document Types containing RichText Editor fields for them to enter the required text and images.
Tab: Generic Properties
H2 (h2), Type: Richtext editor
Article Description (articleDescription), Type: Richtext editor
Article Feature Image (articleFeatureImage), Type: Media Picker
Label (label), Type: Label
In the Template I have then inserted an Umbraco page field which references the relevant Document Type:
<div class="rel-art">
<umbraco:Item field="relatedContent1" runat="server" />
</div>
However, when I view the page in a browser, all I'm getting on the page is the Document Type ID:
<div class="rel-art"> 1202 </div>
I have tried setting it up and inserting it as a xslt:
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:template match="/">
<xsl:value-of select="umbraco.library:GetXmlNodeById($currentPage/data [#alias = 'relatedContent1'])/#nodeName"/>
</xsl:template>
</xsl:stylesheet>
My "Visualise XSLT" button isn't working though so I don't know what is would say at this point. I don't get a modal window. (I'm working remotely onto my client's system so that may have an impact.)
Now, if I insert the accompanying Macro into my template:
<div class="rel-art">
<umbraco:Macro Alias="RelatedContent1" runat="server"></umbraco:Macro>
</div>
that results in not even the ID showing when I view the page:
<div class="rel-art"> </div>
I have tried with and without #nodeName, but no difference.
What is happening? What am I doing wrong? The only thing I can think of is that I had some trouble getting another Document Type to show up on the page until I changed its only Property Type from RichText Editor to Textstring. But I tried that with this one as well, and that didn't make any difference.
I am using Umbraco v4.9, if that helps.
Any help is gratefully received!
Thanks! :-)
Trine,
It is not very clear, but I noticed that the returned value is ' 1202 ' (having spaces). Could you please check your code with a static value i.e.
<xsl:value-of select="umbraco.library:GetXmlNodeById(1202)/#nodeName"/>
if this works fine, then the problem is your 'relatedContent1'. You can Trim its value and use it in GetXmlNodeById function.
It appears as if you are trying to display an image chosen with a media picker. If this is the case then you should use the GetMedia method:
<xsl:value-of select="umbraco.library:GetMedia($currentPage/data[#alias='relatedContent1'], 'false')/data[#alias='umbracoFile']" />
Check out How to use umbraco.library GetMedia in XSLT by Lee Kelleher for more details and for a more fool proof approach for getting media.

Resources