Map optional element to required element - biztalk

In my source schema I have an optional element, in my destination I have a required element.
If the source exists I have to map it directly to the destination, otherwise I need to generate a GUID and assign it to the destination. How do I do this?

If you're not using xslt for your mapping:
Test for existence using the "Logical Existence" functoid -> "Logical Not" functoid -> "Value Mapping" functoid. This checks to see if the node in the input does not exist, if it does not, then use the value mapping to set the value. You can put a hard coded value in the value mapper directly, or hook it to some other input. You may need to do a bit more work if your input node exists but is blank.
There are lots of examples on the internet.

Related

XQuery: generate a variable name from string (attribute value)

I have a framework which runs my xquery and it includes an XML config file that defines the parameters I can use in the query as variables, like this:
<text name="myVar" label="My Var"/>
This means that the user will have a dialog with a field called "My Var", whose value I can then access as $myVar in my query. I don't know how the variable is declared and have no access to the XQuery code that runs my query.
But I want to access my params in a generic way, e.g. go through all of them, check if empty, create a table with labels and values in HTML. I do have access to the XML config file. That means I have to access the value of
$(/config/text/#name)
(The above does not work obviously).
How is it possible?
Well, variable names such as $myVar can only be defined statically, so this isn't going to be possible unless you actually generate the source code of your query programmatically from what you find in the config file.
I think what I would do here is to pass the parameters as a map:
declare variable $params as map(xs:string, item()*);
do-something-with($params('myVar'));
The entries in the map can be accessed either statically ($params?myVar) or dynamically ($params('myVar'))

Can you map a fixed value using the standard BizTalk mapper

Normally, I create my BizTalk mappings in the XSL. Today I was playing around with the mapper but I am failing to do the most basic thing and googling it fails me (I find unrelated questions or the basic way to do it in XSL)
The question is simple though, I want to use the BizTalk mapper (btm file) to map one element to another and fill a second element with a fixed value.
Looking at the functoids, I have a date functoid which gets today's date but nothing to just type some text and map it.
Am I missing something very obvious?
The "built in" way to do this is to set the Value property on the destination node in the map (you can also use this property to desginate that an empty node should be created for this destination node). Unfortunately, this method offers no visual representation that the node is being set this way, except that it will prevent you from linking other nodes/functoids to that destination node. This may lead future devs (or your future self) to think the node isn't being set, or be confused as to why it's being set when it has no inputs.
To get around this, I've frequently used either a String Concatenate functoid (with the fixed value as the only parameter, manually typed in) or a Value Mapping functoid (set "true" as the first parameter and the fixed value as the second parameter). This offers a few benefits:
Visually shows that node is being set by the map
Allows you to set a meaningful label and/or comment on the functoid to denote why you're setting that value.

Biztalk Distinguished field issue

I'm passing a message in biztalk that is resulting in the following suspended message:
Inner exception: A failure occurred while evaluating the distinguished
field MessageStatus against the message part data. The message part
data does not contain at least one of the nodes specified by the XPath
expression (listed below) that corresponds to the distinguished field.
The cause for this error may be that the message part data has not
been initialized or that the message part data does not conform to the
message
In my orchestration I'm using a map that maps an ID called textID to the textID field in my constructed message "MessageAttempt". I also have a field called MessageStatus with the value set to "Nothing" not to be confused with .
After my map I use a message assignment shape to set the MessageAttempt.MessageStatus element to "Attempted" with the following code:
Message_MessageAttempt.MessageStatus = var_Attempt;
I been trying to figure this out all day. I have a similar ConstructedMessage/Transform/Assignment shape on a different branch in my orchestration set up the same and works just fine. I'm not sure what I could be missing.
The XPath functoin can't find the element. There are two possible reasons for this.
The element doesn't exist. If it doesn't exist, you have to create it first. You can do this In the map by setting its value property to <empty>, or using an empty String Concatenate functoid with its output into that node.
You should be able to verify this by going into the group hub, opening the suspended message, and viewing the message part. You'll find that it doesn't contain the node the XPath refers to.
The namespaces in the message are not qualified properly. XPath in orchestrations runs into issues if you don't use namespace prefixes for the message and just rely on the default/empty xmlns.

BizTalk Business Rule for checking against list of values contained in .csv, xml, etc

I'm new to BRE and fairly new to BizTalk as a whole, so this may be quite simple and just evading me...
What I'd like to do is this: create a business rule in BRE that takes as an input the incoming message and checks to see if a value contained in message matches any of the values within a specified set of values. A sample message is as follows. The <isFound> field would then be updated accordingly.
<n1:DocumentTemplate xmlns:n1="mynamespace">
<rootOid>2.16.840.1.113883.3.51.60.2.5</rootOid>
<isFound>false</isFound>
</n1:DocumentTemplate>
Basically I'd like to match the <rootOid> node against a list of values. I've already created a business that will match the <rootOid> against a hardcoded value in the Conditions of the business rule...just as a proof of concept to learn the basics of how to use the BRE and call a rule in an orchestration.
I'm failing to find a way to match against a list of values beyond doing a giant list of hard-coded ORs in the "Conditions" of the Business Rule. The list of accepted values is large enough that doing a bunch of ORs is not going to work.
Ideally, I'd like to have a maintainable XML file full of acceptable <rootOid> values to check against from within the business rule.
I also realize that there is a way to call a database and read the values from a table/column for matching, but I'd rather keep SQL out of the equation so that this can be a little more self-contained.
One "Equal" expression is enough. Your RHS fact should be another vocabulary item. In case of XML type a proper path will pull all values one by one and cause multiple evaluations and respectively firing an action if there's a match. The key to remember: BRE is a pattern matching engine.
The vocabulary is just a convenient alias for the fact definition. Let's say you create an XML file with the following structure:
<options>
<value>A</value>
<value>B</value>
<value>C</value>
</options>
Define a vocabulary for this fact as
Name: PossibleValues
XPath Selector: /options/value
XPath Field: .
Then defining a rule as IF currentValue == PossibleValues will cause three condition evaluations as the RHS yields three facts into the working memory. Consequently, only those that were true will fire a rule (Action). Compare this to the default definition BRE creates when you pick a node from the XML schema which will only assert one (first) fact:
XPath Selector: /options/
XPath Field: value
(namespaces omitted for brevity)
At runtime pass this XML document as an argument to the BRE (whether in the orchestration or in .Net component depending on BRE invocation context). At design time for testing you have to implement Fact Creator component (implements IFactCreator) to provide an instance of required arguments.
Long-term facts (like the one in the question) are better managed using custom fact retrievers. Fact retriever is a .Net component that implements IFactRetriever. See the documentation for details. Inside fact retriever implementation load XML (from disk) and assert it into the working memory as TypedXmlDocument.

Index Specific Type without Its Contained Types

I add a FieldIndex for my content type according to the Plone.org instructions.
In the ZMI, I can see the indexed items at /mysite/portal_catalog/Indexes/Building. My content type (providing IMyType, with one field building) is folderish and contains a Photo (providing IPhoto, without building field) as allowed_content_types in profiles/default/types/MyType.xml file.
I want indexing only for MyType's building field. However, it seems items of Photo type get indexed with the value from their parents. That's annoying. Does the code #indexer(IMyType) mean indexing for IMyType and its contained types? How can I index only for IMyType?
What an indexer does is to get the attribute directly from the object being indexed. In Plone that is as special wrapper, one that will use registered indexers (as created with the #indexer decorator) if they exist.
However, if you index happens to index building and that is also an attribute on your IMyType objects directly, any contained objects will have that attribute through acquisition as well. Registering an indexer for IMyType does not prevent this.
There are a few ways around this:
Use a different name for your indexer, one that doesn't match the attribute name. Note that if all you do is index an attribute the indexer is redundant though, the index could just as well retrieve the attribute directly.
Register a "catch all" indexer:
from zope.interface import Interface
#indexer(Interface)
def catchall_ignore(ob, **kw):
# Raising AttributeError means: do not index anything
raise AttributeError
Instead of direct attribute access, now this indexer method will be used instead for Photos, causing the indexer to not register a value for building.
This is how acquisition works.
here how to workaround this:
http://plone.293351.n2.nabble.com/how-to-prevent-portal-catalog-from-indexing-acquisition-values-td2650735.html
"use a custom indexer that does the aq_explicit check."

Resources