All data in BAO is XML. Even data that doesn't look like XML when you enter it gets wrapped in <value> tags so it is valid XML. Entering a string in an assignment activity input panel gets wrapped in <value> tags. Most of the time, this is a transparent process and developers have no issues with this.
The secret is that BAO treats any XML that is only one level deep as a string. When it outputs XML like this, it will automatically remove the enclosing tags so it looks like a non-XML string again. It will even do when the enclosing tags are not named <value>, it will remove any element tag when it prints a "string".
<crazy-element-name>This is a string!</crazy-element-name>
<value> <string>This is not a string. This is XML</string> </value>
BAO does this everywhere. For example:
- Printing to logs
- Tokens in transform editors
- Input text boxes that contain context item objects
- OCP dialogs
- Maybe others, you can post below if you find one
In the last month or so I've had a couple of support cases where developers ran into problems having to do with how BAO handles what it considers strings. The problem was the "Parameter type" drop-down in the input selection of an assign activity set to "String" when it should have been "XML". BAO does not treat an input parameter type of "String" the same as it does "XML". Entering XML in the input box when the drop-down is set to "String" will destroy the XML.
Try this experiment: In a new process, create an assign activity that puts a string in a context on the first assign row.
In a second assign row, feed that context into this XSLT transform:
You can't do this on a single assign activity row because Studio won't allow you to create a transform for a string value.
When run, if your string is "I am a string!", you will see the following:
<new-element> <value>I am a string!</value> </new-element>
The "Copy-of" node will copy the entire input XML so we can see the <value> tags that get added.
Something similar happens when you put XML into the input panel with the "Parameter type" set to "String". In addition to wrapping the "string" in an XML <value> element, BAO also escapes the illegal XML characters in the "string". The characters <, >, &, and others are illegal in XML values, because they are XML markup characters. This has the side effect of destroying any XML entered. The problem often isn't immediately noticeable because BAO always converts escaped text back to the normal form when printing.
In another workflow, put some XML in an assign activity input panel with Parameter type set to 'String":
The contents of "string context" are now:
<value><list><value>this is a string, NOT!</value></list></value>
But is will always print in Dev Studio and in the processes.log file as what it looked like in the input box. If this was instead XML that was going to end up in an adapter request, that adapter call probably won't work.
To see this, we'll write the "string context" context item above to a file with the file adapter. Add another row to the assign activity like so:
We feed the context item "request" into a Call Adapter activity, pick a file adapter, and set up some logging for the request and the response. When we run the resulting workflow, the processes logging in the Console Window even falsely shows everything is going to be okay:
[request= <request-data> <fileRequest> <filename>C:\\broken-xml.txt</filename> <character-set>cp437</character-set> <filetype>XML</filetype> <lines> <line><list> <value>this is a string, NOT!</value> </list></line> </lines> </fileRequest> </request-data>]
But the actual contents of "C:\broken-xml.txt" are:
<?xml version="1.0" encoding="UTF-8"?> <lines> <line><list> <value>this is a string, NOT!</value> </list></line> </lines>
Which is most likely not what you were expecting to write into this file, if this was a real attempt to write data into a file.
You'll notice in the broken-xml.txt file, if you decode all the escaped characters, there are no <value> elements surrounding the destroyed XML. That is the last part of how strings are treated by the assign activity input panel.
To see what happened, take the first workflow above that showed us the <value> tags added to the string, and replace the assign activity row with the XSLT transform above with something like the following:
The results of this, when run, are:
[some XML=I am a string!]
No XML tags, even tho we might have expected some. What happened is this:
When placing a context item with a "string" in it in the input panel as I've done above, the string is unwrapped from its XML tags, so that those tags don't show up in the resulting XML. This is a feature. It would otherwise be impossible use the input panel as I did to create a valid adapter request.
What is in the "some XML" context item is actually:
<new-element>I am a string!</new-element>
If you used the XSLT transform above, you could verify this. When that is printed into the Console window, what gets printed is printed without the <new-element> tags, because those tags are only one level deep, meaning this will be printed as a string.
The Studio console window and processes.log will show the un-escaped text, which will often look perfectly normal. When you are dealing with adapter requests and actual data, it can be difficult to find out that some or all of the XML is actually escaped. Usually, the first clue that this is the issue comes from DEBUG logging in grid.log once you've opened a BMC Support case, and we've asked you for adapter debug logging. The output in grid.log from debug logging doesn't usually escape the XML going into adapters.
Let's go back to the XML test case where we write the broken XML into a file. If I change the Parameter type to "String", with the same request XML in it, like so:
The workflow will compensate with an error, or maybe it won't but you won't get any data back. There are lots of actual errors you can get, depending on just how the adapter request is borked. When using the AutoPilot wrapper modules, where the whole adapter request is formed out of parts, where maybe only some of the parts are XML broken by being escaped, the error might not really tell you what is wrong. Adapter debug logging is usually where you'll first notice the escaped strings.
When we run the above, the compensation we get is:
An error occurred that triggered compensation: Summary: Execution failed. Caused by: Summary: XML being processed is invalid. Detail: The XML is considered to be in an invalid format due to the following reason "The adapter request data was not found in the XML", and processing cannot proceed. The XML being processed was: <value><request-data> <fileRequest> <filename>C:\\broken-xml.txt</filename> <character-set>cp437</character-set> <filetype>XML</filetype> <lines> <line><list> <value>this is a string, NOT!</value> </list></line> </lines> </fileRequest> </request-data></value>
Note that the actual XML looks okay. It is all pretty, and indented, which is ALWAYS how BAO prints XML. The two clues here we should notice are the <value> tags wrapped around the whole thing, and that there is no line break between the <value><request-data> tags indicating BAO doesn't consider one of them, the inner one, to be XML. The other common clue is that the XML prints all on one line, something BAO doesn't do when printing what it considers to be XML.
Depending on exactly how the adapter request is broken, the results might not have these clues, and might look completely correct. You'll need to verify in the grid.log what is going on.
I've not gone into examples around tokens and the OCP. I'll leave those as an exercise for the teeming millions out there.