xpath query not working in BizTalk orchestration - biztalk

I'm trying to rewrite a BizTalk 2010 application and do away with an external assembly, but I seem to be running into xpath problems.
We have a process that stores a healthcare claim (837P) as xml in the database, and we need to extract it later. I have a WCF port calling a stored procedure that returns an xml message that looks something like this:
<ClaimXml_SEL_GetClaimXmlResponse xmlns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo">
<StoredProcedureResultSet0>
<StoredProcedureResultSet0 xmlns="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/ClaimXml_SEL_GetClaimXml">
<Claim><![CDATA[<ns0:X12_00401_837_P (etc.)
So what I need to do is extract the actual 837P message - the part that starts with ns0:X12_00401_837_P.
The helper class is very simple, just has a method like this:
public XmlDocument ExtractClaimXml(XmlDocument xDoc)
{
XmlDocument xReturn = new XmlDocument();
XmlNode node = xDoc.SelectSingleNode("/*[local-name()='ClaimXml_SEL_GetClaimXmlResponse' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo']/*[local-name()='StoredProcedureResultSet0' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo']/*[local-name()='StoredProcedureResultSet0' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/ClaimXml_SEL_GetClaimXml']/*[local-name()='Claim' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/ClaimXml_SEL_GetClaimXml']");
xReturn.LoadXml(node.InnerText);
return xReturn;
}
and then the Message Assignment shape has this code:
rawClaimXml = ClaimXmlResponse;
strippedClaim = XmlHelperClass.ExtractClaimXml(rawClaimXml);
Claim837P = strippedClaim;
...where ClaimXmlResponse; is the message shown above, Claim837P is an 837P message, and rawClaimXml & strippedClaim are xml variables. This works just fine, but it seems excessive to call an external assembly.
I tried this in the assingment shape:
rawClaimXml = xpath(ClaimXmlResponse, "same xpath as above");
strippedClaim.LoadXml(rawClaimXml.InnerText);
Claim837P = strippedClaim;
...but get the error "'UnderlyingXmlDocument.InnerText': .NET property is write-only because it does not have a get accessor".
So then I tried just getting a string from the xpath query:
rawClaimString = xpath(ClaimXmlResponse, "string(same xpath as above)");
rawClaimString = rawClaimString.Replace("<![CDATA[", "");
rawClaimString = rawClaimString.Replace(">]]>",">");
strippedClaim.LoadXml(rawClaimString);
Claim837P = strippedClaim;
...but that's no good. Also tried a variant:
rawClaimXml = xpath(ClaimXmlResponse, "same xpath as above");
rawClaimString = rawClaimXml.InnerXml.ToString();
rawClaimString = rawClaimString.Replace("<![CDATA[", "");
rawClaimString = rawClaimString.Replace(">]]>",">");
strippedClaim.LoadXml(rawClaimString);
Claim837P = strippedClaim;
...but still no good. Any suggestions?
Thanks!

1-
Here's a couple of things you can try:
Wrap the xpath in the string() function. xpath(ClaimXmlResponse,
"string(same xpath as above)");
Append the /text() node to the xpath. xpath(ClaimXmlResponse, "same
xpath as above/text()");
A combination of the two.
Can you elaborate on the goal here? There's nothing wrong with using the helper class. If it's the extra Assembly that's bothering you, you can always add the .cs to the BizTalk Project.
2-
Coming from a different direction, you can use Path option for the Inbound BizTalk message body on the Messages Tab of the WCF-Custom Adpater configuration.

I was also facing the similar issue but when I gone through your various solution I got the solution for my question.
For me this worked **
rawClaimString = xpath(ClaimXmlResponse, "string(same xpath as
above)");
**
thanks for that phew ;)
Coming to the solution for your problem you can distinguishly promote the node that holding your response and try to access that node using .notation and assign it to the sting this ll return the expected output to you :)

Related

aws dynamodb query attribute value that contains special character?

attribute itemJson stored as follow
"itemJson": {
"S": "{\"sold\":\"3\",\"listingTime\":\"20210107211621\",\"listCountry\":\"US\",\"sellerCountry\":\"US\",\"currentPrice\":\"44.86\",\"updateTime\":\"20210302092220\",\"itemLocation\":\"Miami,FL,USA\",\"listType\":\"FixedPrice\",\"categoryName\":\"Machines\",\"itemID\":\"293945109477\",\"sellerID\":\"holiday_for_you\",\"s3Key\":\"US/2021/2/FixedPrice/293945109477.json\",\"visitCount\":\"171\",\"createTime\":\"20210201233158\",\"listingStatus\":\"Completed\",\"endTime\":\"2021-02-28T20:22:57\",\"currencyID\":\"USD\"}"
},
i want to query with filter:contains(itemJson, "sold":"0") with java sdk,i tried those syntax,all fail
expressionValues.put(":v2", AttributeValue.builder().s("\\\"sold\\\":\\\"0\\\"").build());
expressionValues.put(":v2", AttributeValue.builder().s("sold:0"").build());
what is the right way to my filter syntax?
I try #Balu Vyamajala's syntax on the dynamodb web console as follow,did not get the solution yet
contains (itemJson, :subValue) with value of "sold\":\"3\"" seems to be working.
Working example on a Query Api and worked as expected:
QuerySpec querySpec = new QuerySpec()
.withKeyConditionExpression("pk = :v_pk")
.withFilterExpression("contains (itemJson, :subValue)")
.withValueMap(new ValueMap().withString(":v_pk", "6").withString(":subValue", "sold\":\"3\""));
and to test from Aws console we just need to enter "sold":"2"

XQuery (saxon) failing with a schema (XPath works)

I switched in saxon from XPath to XQuery and on the selects where I have a schema I'm getting the error message:
A typed input document can only be used with a schema-aware query
My setup is:
InputSource xmlSource = new InputSource(xmlData);
SAXSource saxSource = new SAXSource(reader, xmlSource);
Source schemaSource = new StreamSource(schemaFile);
Configuration config = createEnterpriseConfiguration();
config.addSchemaSource(schemaSource);
Processor processor = new Processor(config);
SchemaValidator validator = new SchemaValidatorImpl(processor);
DocumentBuilder doc_builder = processor.newDocumentBuilder();
if(!preserveWhiteSpace)
doc_builder.setWhitespaceStrippingPolicy(WhitespaceStrippingPolicy.ALL);
doc_builder.setSchemaValidator(validator);
XdmNode root_node = doc_builder.build(saxSource);
XQueryCompiler compiler = processor.newXQueryCompiler();
Is there something additional I need to do on queries where there is a schema?
thanks - dave
Call XQueryCompiler.setSchemaAware(true);
This isn't the default because it's good for the optimizer to know whether the data is likely to be typed or untyped, and it's inefficient to generate schema-aware code if the data is untyped (conversely, when the data is typed, schema-aware code is typically faster -- though the savings can be eaten up by the extra cost of validating the input).

JSON.Net "Could not read query operator" in SelectTokens

I'm trying to get some info from some JSON I got from magicthegathering.io using the SelectTokens method in JSON.Net. However, when I try to do this I get an error "Could not read query operator".
Here's the code I'm using:
JToken jtoken = JToken.Parse(
#"{""cards"":[{""name"":""Krark-Clan Engineers"",""manaCost"":""{3}{R}"",""cmc"":4,""colors"":[""Red""],""type"":""Creature — Goblin Artificer"",""types"":[""Creature""],""subtypes"":[""Goblin"",""Artificer""],""rarity"":""Uncommon"",""set"":""5DN"",""text"":""{R}, Sacrifice two artifacts: Destroy target artifact."",""flavor"":""\""Well, I jammed the whatsit into the whackdoodle, but I think I broke the thingamajigger.\"""",""artist"":""Pete Venters"",""number"":""70"",""power"":""2"",""toughness"":""2"",""layout"":""normal"",""multiverseid"":50201,""imageUrl"":""http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=50201&type=card"",""foreignNames"":[{""name"":""喀勒克族机械工"",""language"":""Chinese Simplified"",""multiverseid"":81620},{""name"":""Ingénieurs du clan Krark"",""language"":""French"",""multiverseid"":80795},{""name"":""Ingenieure des Krark-Clans"",""language"":""German"",""multiverseid"":80960},{""name"":""Ingegneri di Krark-Clan"",""language"":""Italian"",""multiverseid"":81290},{""name"":""クラーク族の技師"",""language"":""Japanese"",""multiverseid"":80630},{""name"":""Engenheiros do Clã-de-Krark"",""language"":""Portuguese (Brazil)"",""multiverseid"":81455},{""name"":""Ingenieros del clan Krark"",""language"":""Spanish"",""multiverseid"":81125}],""printings"":[""5DN""],""originalText"":""{R}, Sacrifice two artifacts: Destroy target artifact."",""originalType"":""Creature — Goblin Artificer"",""legalities"":[{""format"":""Commander"",""legality"":""Legal""},{""format"":""Freeform"",""legality"":""Legal""},{""format"":""Legacy"",""legality"":""Legal""},{""format"":""Mirrodin Block"",""legality"":""Legal""},{""format"":""Modern"",""legality"":""Legal""},{""format"":""Prismatic"",""legality"":""Legal""},{""format"":""Singleton 100"",""legality"":""Legal""},{""format"":""Tribal Wars Legacy"",""legality"":""Legal""},{""format"":""Vintage"",""legality"":""Legal""}],""id"":""a4d05fd27ec5d7df470e91218f1ca885eda4f0c6""}]}"
);
var foundTokens = jtoken.SelectTokens(#"$..cards[?(#.name=""Krark - Clan Engineers"")].imageUrl", true);
if (foundTokens.Any())
{
string selected = foundTokens.Last().ToString();
Console.WriteLine("Found: " + selected);
}
else
{
Console.WriteLine("Found nothing!");
}
(Here is a fiddle with the same code as shown above.)
When I try to get the same path using online JSONPath testing tools (here or here for example) it works as expected.
Why doesn't this work in JSON.Net? And how can I fix it?
Thanks!
You have to use == for string comparison; = is only for numerical values.
You have to enclose your string in single quotes.
e.g. #.name=='Krark - Clan Engineers')
forked fiddle

Exploding a string ASP

I have the following which is returned from an api call:
<WORST>0</WORST>
<AVERAGE>93</AVERAGE>
<START>1</START>
I need to parse this to just give me the <AVERAGE></AVERAGE> number, 93.
Here's what I'm trying but get error detected:
res = AjaxGet(url)
myArray = split(res,"AVERAGE>")
myArray2 = split(myArray[1],"</AVERAGE>")
response.write myArray2[0]
I'm brand new to ASP, normally code in PHP
VBScript doesn't recognise square brackets [] when accessing Array elements and will produce a Syntax Error in the VBScript Engine.
Try making the following changes to the code snippet to fix this problem;
res = AjaxGet(url)
myArray = split(res,"AVERAGE>")
myArray2 = split(myArray(1),"</AVERAGE>")
response.write myArray2(0)
On a side Note:
Parsing XML data in this way is really inefficient if the AjaxGet() function returns an XML response you could use the XML DOM / XPath to locate the Node and access the value.

Flex3 / Air 2: NativeProcess doesn't accepts standard input data (Error #2044 & #3218)

I'm trying to open cmd.exe on a new process and pass some code to programatically eject a device; but when trying to do this all I get is:
"Error #2044: Unhandled IOErrorEvent:. text=Error #3218: Error while writing data to NativeProcess.standardInput."
Here's my code:
private var NP:NativeProcess = new NativeProcess();
private function EjectDevice():void
{
var RunDLL:File = new File("C:\\Windows\\System32\\cmd.exe");
var NPI:NativeProcessStartupInfo = new NativeProcessStartupInfo();
NPI.executable = RunDLL;
NP.start(NPI);
NP.addEventListener(Event.STANDARD_OUTPUT_CLOSE, CatchOutput, false, 0, true);
NP.standardInput.writeUTFBytes("start C:\\Windows\\System32\\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll");
NP.closeInput();
}
I also tried with writeUTF instead of writeUTFBytes, but I still get the error. Does anyone have an idea of what I'm doing wrong?.
Thanks for your time :)
Edward.
Maybe cmd.exe doesn't handle standardInput like a normal process.
You could try passing what you want to execute as parameters to the cmd process, rather than writing to the standard input
I think
cmd.exe /C "start C:\Windows\System32\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll"
is the format to pass something as a parameter to cmd to execute immediately.
This site has an example of passing process parameters using a string vector:
http://blogs.adobe.com/cantrell/archives/2009/11/demo_of_nativeprocess_apis.html
Try it without the last line "NP.closeInput();"
See also:
http://help.adobe.com/en_US/as3/dev/WSb2ba3b1aad8a27b060d22f991220f00ad8a-8000.html
I agree with abudaan, you shouldn't need to closeInput().
Also, suggest you add a line break at the end of the writeUTFBytes() call, e.g.:
NP.standardInput.writeUTFBytes("start C:\\Windows\\System32\\rundll32.exe shell32.dll,Control_RunDLL hotplug.dll **\n**");
Lastly, I recommend you listen to other events on the NativeProcess, I use a block of code something like this:
NP.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStdOutData);
NP.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onStdErrData);
NP.addEventListener(Event.STANDARD_OUTPUT_CLOSE, onStdOutClose);
NP.addEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, onStdInputProgress);
NP.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, onIOError);
NP.addEventListener(IOErrorEvent.STANDARD_INPUT_IO_ERROR, onIOError);
NP.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError);
with the normal event handler functions that at least trace what they receive.
Best of luck - I've just spent a few hours refining NativeProcess with cmd.exe - its fiddly. But I got there in the end and you will too.

Resources