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.
Related
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 :)
I have the following xml result from this link - https://api.eveonline.com/eve/CharacterID.xml.aspx?names=BorisKarlov
<eveapi version="2">
<currentTime>2013-01-16 18:57:38</currentTime>
<result>
<rowset name="characters" key="characterID" columns="name,characterID">
<row name="BorisKarlov" characterID="315363291"/>
</rowset>
</result>
<cachedUntil>2013-02-16 18:57:38</cachedUntil>
</eveapi>
and I am trying to extract the characterID into asp. I am using the following code,
Set oXML = Server.CreateObject("Msxml2.DOMDocument.6.0")
oXML.LoadXML("https://api.eveonline.com/eve/CharacterID.xml.aspx?names=BorisKarlov")
Set oRoot = oXML.selectSingleNode("//result")
For Each oNode In oRoot.childNodes
response.Write oNode.Attributes.getNamedItem("characterID").Text
Next
Set oXML = Nothing
All i keep getting is the following error:
Microsoft VBScript runtime error '800a01a8'
Object required: 'oRoot'
.............
I can only assume that Set oRoot = oXML.selectSingleNode("//result") is not actually generating any data and therefore throwing up the error in the next line.
Can anyone please shed some light on my problem?
You have a few problems there.
loadXML() is for loading a block of XML as a string, not fetching from a remote server; for that, you need to use load()
when loading from a server, you need to tell it to use the ServerXMLHTTP component, and set async to false so that it waits until loaded before executing the rest of your script.
when I tried loading that XML, I got an encoding error; you will need to resolve that one way or another
when I loaded the XML directly from a string, it wouldn't parse because there is a script element containing non-XML content; that needs to be contained within a CDATA section
your XPath query is to //result, but you actually need it to be //result/rowset
This code should work once you resolve issues 3 and 4 above:
Set oXML = Server.CreateObject("Msxml2.DOMDocument.6.0")
oXML.async = False
oXML.setProperty "ServerHTTPRequest", true
oXML.Load("https://api.eveonline.com/eve/CharacterID.xml.aspx?names=BorisKarlov")
If oXML.parseError.errorCode <> 0 Then
Response.Write "<p>XML parse error: " & Server.HTMLEncode(oXML.parseError.reason) & "</p>"
Else
Set oRoot = oXML.selectSingleNode("//result/rowset")
If oRoot Is Nothing Then
response.write "Nothing!"
response.end
End If
For Each oNode In oRoot.childNodes
response.Write oNode.Attributes.getNamedItem("characterID").Text
Next
End If
Set oXML = Nothing
Edit: to get around the problem #3, and oddly also #4 (don't know why!), use this snippet to load the XML instead. For some reason, I think the code above isn't handling the gzip compressed stream correctly, but this code below does.
Set oXML = Server.CreateObject("Msxml2.DOMDocument.6.0")
Set xh = Server.CreateObject("Msxml2.ServerXMLHTTP.6.0")
xh.open "GET", "https://api.eveonline.com/eve/CharacterID.xml.aspx?names=BorisKarlov", False
xh.send
xml = xh.responseText
oXML.LoadXML xml
How I can solve this error message
Microsoft VBScript runtime error
'800a01a8' Object required: 'lUATRef'
/cmgtest/transaction/viewPCReqForm.asp,
line 284
this is some source code that I wrote below
function checkUATReq(aUATRef)
Dim correctness,lUATRef,uatRef
correctness = False
lUATRef = aUATRef
uatRef = lUATRef.Substring(1,2)
rwriteln uatRef
'sqlCheckUATReq = "select * from PC_DETAIL where ID ='"&uatReqRef&"'"
'rwriteln uatReqRef
End function
Seems like your function isn't getting a parameter passed to it. Check whether aUATRef is getting initialized.
In VBScript, Strings aren't objects. You should use the Mid function to get a portion of a string:
uatRef = Mid(IUATRef, 1, 2)
Dim custEmail As String
Dim inputEmail As String
custEmail = dt.Rows(0).Item("email")
inputEmail = email_add.Text
if (custEmail.toString() == inputEmail.toString() ){
label1.Text = custEmail
}
End If
This code is giving an error: Compiler Error Message: BC30201: Expression expected.
I just basically want to check if two values are equal but its saying something about expression expected although i've given the expression to evaluate.
The above is a mix of vb.net and c# syntax. You can use either in .net with success but not both at the same time. Get rid of the { and } to stick with vb.
Looks like you are mixing C# and VB.Net. Assuming you are using VB.Net
Replace the '{' with Begin IF and remove the '}'.
For example, how can I run me.test below?
myvar = 'test'
me.myvar
ASP looks for the method "myvar" and doesn't find it. In PHP I could simply say $me->$myvar but ASP's syntax doesn't distinguish between variables and methods. Suggestions?
Closely related to this, is there a method_exists function in ASP Classic?
Thanks in advance!
EDIT: I'm writing a validation class and would like to call a list of methods via a pipe delimited string.
So for example, to validate a name field, I'd call:
validate("required|min_length(3)|max_length(100)|alphanumeric")
I like the idea of having a single line that shows all the ways a given field is being validated. And each pipe delimited section of the string is the name of a method.
If you have suggestions for a better setup, I'm all ears!
You can achieve this in VBScript by using the GetRef function:-
Function Test(val)
Test = val & " has been tested"
End Function
Dim myvar : myvar = "Test"
Dim x : Set x = GetRef(myvar)
Response.Write x("Thing")
Will send "Thing has been tested" to the client.
So here is your validate requirement using GetRef:-
validate("Hello World", "min_length(3)|max_length(10)|alphanumeric")
Function required(val)
required = val <> Empty
End Function
Function min_length(val, params)
min_length = Len(val) >= CInt(params(0))
End Function
Function max_length(val, params)
max_length = Len(val) <= CInt(params(0))
End Function
Function alphanumeric(val)
Dim rgx : Set rgx = New RegExp
rgx.Pattern = "^[A-Za-z0-9]+$"
alphanumeric = rgx.Test(val)
End Function
Function validate(val, criterion)
Dim arrCriterion : arrCriterion = Split(criterion, "|")
Dim criteria
validate = True
For Each criteria in arrCriterion
Dim paramListPos : paramListPos = InStr(criteria, "(")
If paramListPos = 0 Then
validate = GetRef(criteria)(val)
Else
Dim paramList
paramList = Split(Mid(criteria, paramListPos + 1, Len(criteria) - paramListPos - 1), ",")
criteria = Left(criteria, paramListPos - 1)
validate = GetRef(criteria)(val, paramList)
End If
If Not validate Then Exit For
Next
End Function
Having provided this I have to say though that if you are familiar with PHP then JScript would be a better choice on the server. In Javascript you can call a method like this:-
function test(val) { return val + " has been tested"; )
var myvar = "test"
Response.Write(this[myvar]("Thing"))
If you are talking about VBScript, it doesn't have that kind of functionality. (at least not to my knowledge) I might attempt it like this :
Select myvar
case "test":
test
case "anotherSub":
anotherSub
else
defaultSub
end select
It's been a while since I wrote VBScript (thank god), so I'm not sure how good my syntax is.
EDIT-Another strategy
Personally, I would do the above, for security reasons. But if you absolutely do not like it, then you may want to try using different languages on your page. I have in the past used both Javascript AND VBScript on my Classic ASP pages (both server side), and was able to call functions declared in the other language from my current language. This came in especially handy when I wanted to do something with Regular Expressions, but was in VBScript.
You can try something like
<script language="vbscript" runat="server">
MyJavascriptEval myvar
</script>
<script language="javascript" runat="server">
function MyJavascriptEval( myExpression)
{
eval(myExpression);
}
/* OR
function MyJavascriptEval( myExpression)
{
var f = new Function(myExpression);
f();
}
*/
</script>
I didn't test this in a classic ASP page, but I think it's close enough that it will work with minor tweaks.
Use the "Execute" statement in ASP/VBScript.
Execute "Response.Write ""hello world"""
PHP's ability to dynamically call or create functions are hacks that lead to poor programming practices. You need to explain what you're trying to accomplish (not how) and learn the correct way to code.
Just because you can do something, doesn't make it right or a good idea.
ASP does not support late binding in this manner. What are you trying to do, in a larger sense? Explain that, and someone can show you how to accomplish it in asp.
Additionally, you might consider "objectifying" the validation functionality. Making classes is possible (though not widely used) in VB Script.
<%
Class User
' declare private class variable
Private m_userName
' declare the property
Public Property Get UserName
UserName = m_userName
End Property
Public Property Let UserName (strUserName)
m_userName = strUserName
End Property
' declare and define the method
Sub DisplayUserName
Response.Write UserName
End Sub
End Class
%>