Problem with BizTalk multi-input map - mapping

I have a map that takes 2 input messages, like this:
<ns0:Root>
<InputMessagePart_0>
<root>
<Indicator>1</Indicator>
<NewValue>AAA</NewValue>
</root>
<InputMessagePart_0>
<InputMessagePart_1>
<root>
<Value>BBB</Value>
</root>
<InputMessagePart_1>
</ns0:Root>
(Lots of the nodes are not shown for clarity)
The ouput message looks like this:
<Root>
<Value>AAA</Value>
</Root>
(It's identical to InputMessagePart_1)
If the Indicator is 1, I want Value to be replaced with NewValue. If it's 0, I want Value to stay the same. I used a scripting functoid with code like this:
public string Get_Value(string indicator, string value, string newValue)
{
if(indicator == "1")
{
return newValue;
}
else
{
return value;
}
}
I'm running into problems due to the fact that Value might not actually occur in the original InputMessagePart_1 - if it doesn't, I want to create it. With the script above, even though Indicator is 1, I'm not getting a return string when Value doesn't exist.
Any suggestions?
Updated: I did some further testing by removing the if/then logic and just returned a hard-coded string from the functoid, and I get the same results... it seems that just having the empty input kills the entire functionality of the functoid...

You should want to use the Equal functoid and test whether the value is 1. You'll then feed the result to the input of two functoids:
First, to a Value Mapping functoid, which is connected to the <New Value> tag in the first part of the source schema.
Second, to a Logical Not functoid, which is then connected to another Value Mapping functoid connected to the <Value> tag in the second part of the source schema.
If the <Indicator>; tag does not contain the expected value 1 or is not present in the source message, the Logical Equal functoid will return False, and the second branch of the map will execute.
It doesn't matter whether the Value tag is present in the second part of the source schema. If it is not, either one of the Value Mapping functoids will create it in the destination.
If you definitely need to depend upon the <Indicator> tag, you might want to use the Logical Existence functoid, that returns whether any specified input node appears in the source message.

If all else fails using the mapper, you might try switching to XSLT - see here how to scrape the XSLT out of your existing BTM.
The map that you are after looks straightforward:
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > .. etc ... whatever you've scraped out
<xsl:output ...
<xsl:template match=...>
<ns1:Root>
<ns1:Value>
<xsl:choose>
<xsl:when test="/ns0:Root/ns0:InputMessagePart_0/ns0:root/ns0:Indicator/text()='1'">
<xsl:value-of select="/ns0:Root/ns0:InputMessagePart_0/ns0:root/ns0:NewValue/text()" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="/ns0:Root/ns0:InputMessagePart_1/ns0:root/ns0:Value/text()" />
</xsl:otherwise>
</xsl:choose>
<ns1:Value>
</ns1:Root>

Related

Receiving responses of different formats for the same query in vespa

I have such schema
schema embeddings {
document embeddings {
field id type int {}
field text_embedding type tensor<double>(d0[960]) {
indexing: attribute | index
attribute {
distance-metric: euclidean
}
}
}
rank-profile closeness {
num-threads-per-search:1
inputs {
query(query_embedding) tensor<double>(d0[960])
}
first-phase {
expression: closeness(field, text_embedding)
}
}
Such services:
...
<container id="query" version="1.0">
<search/>
<nodes>
<node hostalias="query" />
</nodes>
</container>
<content id='mind' version='1.0'>
<redundancy>1</redundancy>
<documents>
<document type='embeddings' mode="index"/>
</documents>
<nodes>
<node hostalias="content1" distribution-key="0"/>
</nodes>
</content>
...
Then I have the number of queries of the same format:
{
'yql': 'select * from embeddings where ({approximate:false, targetHits:100} nearestNeighbor(text_embedding, query_embedding));',
'timeout': 5,
"hits":100,
'input': {
'query(query_embedding)': [...],
},
'ranking': {
'profile': 'closeness',
},
}
which are then run via app.query_batch(test_queries)
The problem is some responses look like this (and contain id field as integers, just like I inserted):
{'id': 'id:embeddings:embeddings::786559', 'relevance': 0.5703559830732123, 'source': 'mind', 'fields': {'sddocname': 'embeddings', 'documentid': 'id:embeddings:embeddings::786559'}}
and others look like this (neither containing int id as I inserted, nor keeping the format of the previous example):
{'id': 'index:mind/0/b0dde169c545ce11e8fd1a17', 'relevance': 0.49024561522459087, 'source': 'mind'}
How can I make all responses look like the first one? Why are they different at all?
Some of them are filled with content and some are not, I suppose because it timed out. Check the coverage info, and run with traceLevel=3 to see more details.
Some more background info on what's going on:
Searches are executed in two phases: First, minimal information on each hits hit is returned from each content node up to the issuing container. These partial lists are then merged to produce the final hits length list of matches. For those we execute phase two, which is to fill the content of the final hits. This involves doing another request to each of the content nodes to get the relevant content.
If there's little time left, or lots of data, or expensive summary features to compute, or a slow disk subsystem or network, or a node in some kind of trouble, this may time out leaving only some hits filled so that you'll see this.
Why are the id's not the true document id in these cases? The text string id is stored in the disk document blob but not in memory as an attribute, so it needs to be fetched in the fill phase too. If it is not, an internally generated unique id is used instead.

AntSCript to extract xml tag having specific matching string in attribute value from xml file

I have and XML file as below
<sca:composite xmlns:sca="http://www.osoa.org/xmlns/sca/1.0" xmlns:atleastonce="http://www.tibco.com/wrm/policy/atleastonce" xmlns:common="http://xsd.tns.tibco.com/n2/models/common" xmlns:compositeext="http://schemas.tibco.com/amx/3.0/compositeext" xmlns:jdbc="http://xsd.tns.tibco.com/amf/models/sharedresource/jdbc" xmlns:pbu="http://www.tibco.com/wrm/policy/pbu" xmlns:pfe="http://xsd.tns.tibco.com/n2/models/pfe/1.0" xmlns:scact="http://xsd.tns.tibco.com/amf/models/sca/componentType" xmlns:scaext="http://xsd.tns.tibco.com/amf/models/sca/extensions" xmlns:service="http://xsd.tns.tibco.com/bx/amx/model" xmlns:smtp="http://xsd.tns.tibco.com/amf/models/sharedresource/smtp" xmlns:soapbt="http://xsd.tns.tibco.com/amf/models/sca/binding/soap" xmlns:startservicefirst="http://www.tibco.com/wrm/policy/startservicefirst" xmlns:threading="http://www.tibco.com/wrm/policy/threading" xmlns:transactedoneway="http://www.tibco.com/wrm/policy/transactedoneway" xmlns:webapp="http://xsd.tns.tibco.com/amf/models/sca/implementationtype/webapp" xmlns:wrm="http://www.tibco.com/wrm" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" compositeext:formatVersion="2" compositeext:version="1.0.0.20180112132229840" name="za.co.rmb.dealamendmentsmaintenance" targetNamespace="http://www.example.com/za.co.rmb.dealamendmentsmaintenance" xmi:id="_4EfRQfeKEeeZRvktH3XIjg" xmi:version="2.0">
<sca:reference multiplicity="0..1" name="WorkListService_Consumer1" promote="dealAmendmentsMaintenanceProcessFlow/WorkListService_Consumer" wiredByImpl="false" xmi:id="_AR2UQPeLEeeZRvktH3XIjg">
<sca:interface.wsdl interface="http://services.brm.n2.tibco.com#wsdl.interface(WorkListService)" scaext:wsdlLocation=".processOut/process/dealAmendmentsMaintenance.xpdl/brm.wsdl" xmi:id="_AR2UQfeLEeeZRvktH3XIjg"/>
</sca:reference>
<sca:reference multiplicity="0..1" name="CreateDailyTasks_Consumer1" promote="dealAmendmentsMaintenanceProcessFlow/CreateDailyTasks_Consumer" wiredByImpl="false" xmi:id="_ATRQkPeLEeeZRvktH3XIjg">
<sca:interface.wsdl interface="http://www.tibco.com/bs3.0/_8uwIINbzEeWTpucOvGErRg#wsdl.interface(CreateDailyTasks)" scaext:wsdlLocation=".processOut/process/dealAmendmentsMaintenance.xpdl/dealAmendments_segregation.wsdl" xmi:id="_ATRQkfeLEeeZRvktH3XIjg"/>
</sca:reference>
</sca:composite>
With ant script i want to extract value in the "interface" attribute under sca:interface, by matching input value in "name" attribute in sca:refernce.
So lets say
if input will be : WorkListService_Consumer1
Expected Output : http://services.brm.n2.tibco.com#wsdl.interface(WorkListService)
Similarly, if
input will be : CreateDailyTasks_Consumer1
Expected Output : http://www.tibco.com/bs3.0/_8uwIINbzEeWTpucOvGErRg#wsdl.interface(CreateDailyTasks)
I tried using various xmltask commands but i am not getting succesfull.
Thanks
Shrijeet Sinha
You almost had the solution, however text() is used to reference the inner text of an XML element, such as <element>This text here</element>. Here is the syntax for referencing an attribute's value:
<xmltask source="xmlfile.xml">
<copy path="sca:composite/sca:reference[#name='${input}']/sca:interface.wsdl/#interface" property="testproperty"/>
</xmltask>

Rails nokogiri parse XML file

I'm a little bit confused: could not find in web good examples of parsing xml with nokogiri...
example of my data:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<rows SessionGUID="6448680D1">
<row>
<AnalogueCode>0451103079</AnalogueCode>
<AnalogueCodeAsIs>0451103079</AnalogueCodeAsIs>
<AnalogueManufacturerName>BOSCH</AnalogueManufacturerName>
<AnalogueWeight>0.000</AnalogueWeight>
<CodeAsIs>OC90</CodeAsIs>
<DeliveryVariantPriceAKiloForClientDescription />
<DeliveryVariantPriceAKiloForClientPrice>0.00</DeliveryVariantPriceAKiloForClientPrice>
<DeliveryVariantPriceNote />
<PriceListItemDescription />
<PriceListItemNote />
<IsAvailability>1</IsAvailability>
<IsCross>1</IsCross>
<LotBase>1</LotBase>
<LotType>1</LotType>
<ManufacturerName>KNECHT/MAHLE</ManufacturerName>
<OfferName>MSC-STC-58</OfferName>
<PeriodMin>2</PeriodMin>
<PeriodMax>4</PeriodMax>
<PriceListDiscountCode>31087</PriceListDiscountCode>
<ProductName>Фильтр масляный</ProductName>
<Quantity>41</Quantity>
<SupplierID>30</SupplierID>
<GroupTitle>Замена</GroupTitle>
<Price>203.35</Price>
</row>
<row>
<AnalogueCode>0451103079</AnalogueCode>
<AnalogueCodeAsIs>0451103079</AnalogueCodeAsIs>
<AnalogueManufacturerName>BOSCH</AnalogueManufacturerName>
<AnalogueWeight>0.000</AnalogueWeight>
<CodeAsIs>OC90</CodeAsIs>
<DeliveryVariantPriceAKiloForClientDescription />
<DeliveryVariantPriceAKiloForClientPrice>0.00</DeliveryVariantPriceAKiloForClientPrice>
<DeliveryVariantPriceNote />
<PriceListItemDescription />
<PriceListItemNote>[0451103079] Bosch,MTGC#0451103079</PriceListItemNote>
<IsAvailability>1</IsAvailability>
<IsCross>1</IsCross>
<LotBase>1</LotBase>
<LotType>0</LotType>
<ManufacturerName>KNECHT/MAHLE</ManufacturerName>
<OfferName>MSC-STC-1303</OfferName>
<PeriodMin>3</PeriodMin>
<PeriodMax>5</PeriodMax>
<PriceListDiscountCode>102134</PriceListDiscountCode>
<ProductName>Фильтр масляный</ProductName>
<Quantity>5</Quantity>
<SupplierID>666</SupplierID>
<GroupTitle>Замена</GroupTitle>
<Price>172.99</Price>
</row>
</rows>
</root>
and ruby code:
...
xml_doc = Nokogiri::XML(response.body)
parts = xml_doc.xpath('/root/rows/row')
with the help of xpath i could do this? also how to get this parts object (row)?
You're on the right track. parts = xml_doc.xpath('/root/rows/row') gives you back a NodeSet i.e. a list of the <row> elements.
You can loop through these using each or use row indexes like parts[0], parts[1] to access specific rows. You can then get the values of child nodes using xpath on the individual rows.
e.g. you could build a list of the AnalogueCode for each part with:
codes = []
parts.each do |row|
codes << row.xpath('AnalogueCode').text
end
Looking at the full example of the XML you're processing there are 2 issues preventing your XPath from matching:
the <root> tag isn't actually the root element of the XML so /root/.. doesn't match
The XML is using namespaces so you need to include these in your XPaths
so there are a couple of possible solutions:
use CSS selectors rather than XPaths (i.e. use search) as suggested by the Tin Man
after xml_doc = Nokogiri::XML(response.body) do xml_doc.remove_namespaces! and then use parts = xml_doc.xpath('//root/rows/row') where the double slash is XPath syntax to locate the root node anywhere in the document
specify the namespaces:
e.g.
xml_doc = Nokogiri::XML(response.body)
ns = xml_doc.collect_namespaces
parts = xml_doc.xpath('//xmlns:rows/xmlns:row', ns)
codes = []
parts.each do |row|
codes << xpath('xmlns:AnalogueCode', ns).text
end
I would go with 1. or 2. :-)
First, Nokogiri supports XPath AND CSS. I recommend using CSS because it's more easily read:
doc.search('row')
will return a NodeSet of every <row> in the document.
The equivalent XPath is:
doc.search('//row')
...how to get this parts object (row)?
I'm not sure what that means, but if you want to access individual elements inside a <row>, it's easily done several ways.
If you only want one node inside each of the row nodes:
doc.search('row Price').map(&:to_xml)
# => ["<Price>203.35</Price>", "<Price>172.99</Price>"]
doc.search('//row/Price').map(&:to_xml)
# => ["<Price>203.35</Price>", "<Price>172.99</Price>"]
If you only want the first such occurrence, use at, which is the equivalent of search(...).first:
doc.at('row Price').to_xml
# => "<Price>203.35</Price>"
Typically we want to iterate over a number of blocks and return an array of hashes of the data found:
row_hash = doc.search('row').map{ |row|
{
AnalogueCode: row.at('AnalogueCode').text,
Price: row.at('Price').text,
}
}
row_hash
# => [{:AnalogueCode=>"0451103079", :Price=>"203.35"},
# {:AnalogueCode=>"0451103079", :Price=>"172.99"}]
These are ALL covered in Nokogiri's tutorials and are answered many times here on Stack Overflow, so take the time to read and search.

XSLT 2.0. Loop inside a Function

Hitting my wall here...
I've got the following data where a Primary Employee may have multiple dependents. I need to create a function that will match the Employee's SSN (ab:SSN) against the Dependent_SSN and determine if one of them is a 'Spouse'. If so, then we'll return the Dependent_SSN of the 'Spouse'.
If not, we'll move on and return the next non-'Spouse' Dependent_SSN.
I'm trying to create a function as I think I'll need this more than once. The code snippet resides inside of an existing template that is doing other looping functionality.
I've tried this but Oxygen returns an error:
<xsl:function name="ab:PQB">
<xsl:param name="EE_SSN">
</xsl:param>
<xsl:for-each select="/ab:Report_Data/ab:Report_Entry[ab:Employee_ID=$EE_SSN]/ab:Report_Data/ab:Report_Entry[ab:Employee_ID=$EE_SSN]ab:dependents/ab:Dependent_SSN">
</xsl:for-each>
The Error returned is :
"Engine name: Saxon-PE 9.3.0.5
Severity: fatal
Description: Unexpected token name "wd:dependents" beyond end of expression"
I know I need to test the higher level SSN against looping through the dependents, but like I said "I'm against my wall" :)
Data is here:
<ab:Report_Entry>
<ab:SSN>888881006</ab:SSN>
<ab:Last_Name>Smith</ab:Last_Name>
<ab:First_Name>Kimberly</ab:First_Name>
<ab:dependents>
<ab:Dependent_SSN>888881009</ab:Dependent_SSN>
<ab:Relation ab:Descriptor="Spouse">
</ab:Relation>
</ab:dependents>
<ab:dependents>
<ab:Dependent_SSN>888881004</ab:Dependent_SSN>
<ab:Relation ab:Descriptor="Child">
</ab:Relation>
</ab:dependents>
<ab:dependents>
<ab:Dependent_SSN>888881003</ab:Dependent_SSN>
<ab:Relation ab:Descriptor="Child">
<ab:ID ab:type="Related_Person_Relationship_ID">Child</ab:ID>
</ab:Relation>
</ab:dependents>
<ab:dependents>
<ab:Dependent_SSN>888881001</ab:Dependent_SSN>
<ab:Dependent_ID>1032D-4</ab:Dependent_ID>
<ab:Relation ab:Descriptor="Child">
<ab:ID ab:type="Related_Person_Relationship_ID">Child</ab:ID>
</ab:Relation>
</ab:dependents>
</ab:Report_Entry>
Thank you to any advice!
You might want to define the type of the input parameter and the type of the function result and then you should write a function body returning a value of that type. Currently your description sounds rather procedural, that is not going to work with XSLT/XPath.
As for the error, I think in the path /ab:Report_Data/ab:Report_Entry[ab:Employee_ID=$EE_SSN]/ab:Report_Data/ab:Report_Entry[ab:Employee_ID=$EE_SSN]ab:dependents/ab:Dependent_SSN you need one more slash /ab:Report_Data/ab:Report_Entry[ab:Employee_ID=$EE_SSN]/ab:Report_Data/ab:Report_Entry[ab:Employee_ID=$EE_SSN]/ab:dependents/ab:Dependent_SSN to have a syntactically correct path. That should avoid the syntax error you get but is not likely to return the result you want.

Find child of child which attribute code is equal to the parameter passed on the url - XSL

On this dynamic website,
The url looks something like this : departments/CHEM.html
CHEM is a parameter.
<xsl:param name="dep" select="'CHEM'" />
a piece of the xml is below
<course acad_year="2012" cat_num="5085" offered="Y">
<term term_pattern_code="1" fall_term="Y" spring_term="N">fall term</term>
<department code="CHEM">
<dept_long_name>Department of Chemistry and Chemical Biology</dept_long_name>
<dept_short_name>Chemistry and Chemical Biology</dept_short_name>
</department>
</course> ....
I am trying to get the dept_short_name to use on my H1 tag, but I have not been successful.So far I tried
<h2><xsl:value-of select="course/department/[code={#$dep}]"/></h2>
Any suggestions??? Thanks!
Just use:
<xsl:value-of select="course/department[#code eq $dep]/dept_short_name"/>
Remember:
In XPath 2.0 (XSLT 2.0) use the eq operator for value comparissons -- it is more efficient than the general comparisson operator = which really, only, needs to be used when at least one of its operands is a sequence.
I would try this:
<xsl:value-of select="course/department[#code=$dep]/dept_short_name/text()"/>
That says: find the department element (inside a course element) whose code attribute is the value of parameter "dep", then find the dept_short_name child element, then get the text inside that element.
You have to use the # to say that "code" is an attribute, but "dep" should not have it. I think the {} notation is for use inside attributes of the non-XSLT elements of your stylesheet, so I wouldn't use it inside a value-of expression.

Resources