? How to obtain tags by part of element name - xmldocument

I have the following XML response:
<S:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns0:RespOpReportGen
xmlns:ns7="http://my.service.url/Schemas/folder1"
xmlns:ns4="http://my.service.url/framework/folder2"
xmlns:ns13="http://my.service.url/framework/folder3"
xmlns:ns0="http://my.service.url/framework/folder4">
<ns0:contextResponse>
<ns4:trnResult>
<ns13:trnStatus/>
<ns13:OKNOResponse>B</ns13:OKNOResponse>
<ns13:ApprovalNr>0</ns13:ApprovalNr>
<ns13:trnID>213454567</ns13:trnID>
<ns13:trnDate>2019-03-13T13:02:10.76</ns13:trnDate>
</ns4:trnResult>
</ns0:contextResponse>
<ns0:FileResponse>
<ns7:contentFile>JVBERi0</ns7:contentFile>
<ns7:mimeType>application/pdf</ns7:mimeType>
</ns0:FileResponse>
</ns0:RespOpReportGen>
</S:Body>
</S:Envelope>
I use the following code in order to obtain the value in tag ns7:contentFile
Dim soapResultXml As XmlDocument = New XmlDocument()
soapResultXml.LoadXml(soapResult)
Dim resultado As XmlNodeList = soapResultXml.GetElementsByTagName("contentFile")
... but i got no results.
Is there a way to obtain the tags by part of the name? or ... how can i obtain "ns7:" value to concatenate it with "contentFile" ?
Thanks in advance, and best regards.
EDIT
Dim soapResultXml As XmlDocument = New XmlDocument()
soapResultXml.LoadXml(soapResult)
Dim resultado As XmlNodeList = soapResultXml.SelectNodes("//*[contains(name(),'contentFile')]")
It works too.

You need to add and configure XmlNamespaceManager. Something like this.
Dim soapResultXml As XmlDocument = New XmlDocument()
soapResultXml.LoadXml(soapResult)
Dim xnm as New XmlNamespaceManager(soapResultXml.NameTable)
xnm.AddNamespace("ns7", "http://my.service.url/folder1")
''//add more namespaces
''// xnm.AddNamespace("ns8", "http://my.service.url/folder2")
''//prefix doesn't matter. URI matters.
Dim resultado As XmlNodeList = soapResultXml.SelectNodes("contentFile", xnm)

Related

How do I reach the second child node of an element XML in vbscript?

After spending many hours on the internet I was not able to get this to work and need some help.
XML:
xml snippet highlighting NoteSynopsis
CODE:
set xmlDoc = SERVER.CREATEOBJECT("MSXML2.DomDocument.6.0")
xmlDoc.async = False xmlDoc.Load("D:\GVPApplications\TechSupportCreateIncident\CreateIncidentRequest.xml")
xmlDoc.setProperty "NewParser","true"
set Root = xmlDoc.documentElement
set NodeList1 = Root.getElementsByTagName("IncidentNote")
For Each Elem in NodeList1
if Elem.firstChild.nodename = "Note" then
Elem.firstChild.text = Notes
end if
Next
ISSUE:
As highlighted in the image XML , I need to be able to read "NoteSynopsis" element and its value. As simple as this seems I have not been able to find a solution to this. If this was the last child no issue, I would do a Elem.LastChild.nodename, but this isn't!
You could use the selectSingleNode(...) method and use XPath
set xmlDoc = SERVER.CREATEOBJECT("MSXML2.DomDocument.6.0")
xmlDoc.async = False xmlDoc.Load("D:\GVPApplications\TechSupportCreateIncident\CreateIncidentRequest.xml")
xmlDoc.setProperty "NewParser","true"
xmlDocument.setProperty "SelectionLanguage", "XPath"
Dim firstIncidentNote
set firstIncidentNote = xmlDoc.SelectSingleNode("//IncidentNote")
Dim note
Dim noteSynopsis
set note = firstIncidentNote.GetAttribute("Note")
set note = firstIncidentNote.GetAttribute("NoteSynopsis")
https://msdn.microsoft.com/en-us/library/ms757846(v=vs.85).aspx

Changing node values in XML using VBS with similar names

I am facing this challenge with changing values of nodes in an xml file which has same names, using VBScript. Following is the sample XML:
- <MappingData>
<Name>Name 1</Name>
- <ValueField FieldName="Name 2">
<CharValue>Value 1</CharValue>
</ValueField>
- <ValueField FieldName="Name 3">
<CharValue>Value 1</CharValue>
</ValueField>
My requirement is to change the values of both occurrences of tag
<CharValue>
.
I could have done this if there was any attribute in these tags, but in this case I am stuck.
I tried the following code, but could'nt get what I need.
Set NodeList = objXMLDoc.documentElement.selectNodes("//MappingData/ValueField/CharValue")
For i = 0 To NodeList.length - 1
node.Text = "Value 1"
Next
Any help is appreciated. Thanks.
Try the following code
Set xDoc = CreateObject( "Msxml2.DOMDocument.6.0" )
xDoc.setProperty "SelectionLanguage", "XPath"
xDoc.async = False
xDoc.load "test.xml"
Set nNodes = xDoc.selectNodes("//MappingData/ValueField/CharValue")
For i = 0 To nNodes.Length - 1
nNodes(i).text = "Changed value " & i
Next
xDoc.Save "test.xml"

How can I strip the element using vbscript and display in message box?

I would like to find the price with 2 year contract and display it in a message box. Sofar I have:
Dim MyPage
Dim Price
Set MyPage=CreateObject("Microsoft.XMLDOM")
MyPage.load("http://www.verizonwireless.com/b2c/store/controller?item=phoneFirst&action=viewPhoneDetail&selectedPhoneId=5723")
Wscript.Sleep 2000
Set Price = MyPage.getElementsByTagName("span")
For Each Elem In Price
MsgBox(Elem.firstChild.nodeValue)
Next
I understand that I am completely wrong, but I don't even know where to start. I love writing simple programs like this, but I just need help getting started. Any ideas will help!
Here a better version, uses the HTMLFile object
Dim HTMLDoc, XML, URL, table
Set HTMLDoc = CreateObject("HTMLFile")
Set XML = CreateObject("MSXML2.XMLHTTP")
URL = "http://www.verizonwireless.com/b2c/store/controller?item=phoneFirst&action=viewPhoneDetail&selectedPhoneId=5723"
With XML
.Open "GET", URL, False
.Send
HTMLDoc.Write .responseText
End With
Set spans = HTMLDoc.getElementsByTagName("span")
for each span in spans
WScript.Echo span.innerHTML
next
'=><SPAN>Set Location</SPAN>
'=>Set Location
'=><SPAN>Submit</SPAN>
'=>Submit
'=>Connect with us
the control you use is for reading XML documents, you need something like this
'Create an xmlhttp object, the string depends on the version that is installed
'on your pc could eg also be "Msxml2.ServerXMLHTTP.5.0"
Set xmlhttp = CreateObject("Microsoft.XMLHTTP")
xmlhttp.Open "GET", "http://admin:pasword#10.0.0.2/doc/ppp.htm", False
xmlhttp.Send
text=xmlhttp.responseText
wscript.echo text
Set xmlhttp = Nothing
Run a search in your registry for XMLHTTP to get the right string/version for the identifier.
To get the tag from the html you can use the following
text = "blabla <span>this is what i need</span> bla bla<span>second item</span> end"
function getElementsByTagName(sTextToSeachIn, tag)
answer = ""
separator = ""
set oRegExpre = new RegExp
with oRegExpre
.IgnoreCase = true
.Global = true
.MultiLine = True
.Pattern = "<" & tag & ">(.*?)</" & tag & ">"
end with
set oColMatches = oRegExpre.Execute(sTextToSeachIn)
for each match in oColMatches
answer = answer & separator & match.subMatches(0)
separator = "|" 'use something that's not in the spancontents
next
if separator <> "" then
getElementsByTagName = split(answer, separator)
else
getElementsByTagName = array()
end if
end function
for each tag in getElementsByTagName(text, "span")
wscript.echo tag
next
'=>this is what i need
'=>second item
There are better techniques and certainly better languages than vbscript to do this, i suggest to take a look at Ruby which exels in such things.
Alex, in response to your comment about getting a cookie and running a javascript in HTMLFile, here a ruby script i found, hopes it helps you at some point, it reads in a page, passes it to the HTLMFile object and in that DOM executes a remote javascript file. It also gives you an idea of the combined power of activeX and Ruby.
require "win32ole"
$jsxpath_uri = "http://svn.coderepos.org/share/lang/javascript/javascript-xpath/trunk/release/javascript-xpath-latest-cmp.js"
uri, xpath = "http://gist.github.com/gists", "//div[#class='info']/span/a"
http = WIN32OLE.new('MSXML2.XMLHTTP')
http.Open "GET", uri, false
http.Send
text = http.responseText
dom = WIN32OLE.new("htmlfile")
dom.Write(text)
dom.parentWindow.eval(open($jsxpath_uri){|f| f.read })
items = dom.evaluate(xpath, dom, nil, 7, nil)
len = items.snapshotLength
(0...len).each do |i|
item = items.snapshotItem(i)
puts item.innerHTML
end

CrystalReports DataTable Error VB.NET

I'm trying to pass all data from a DB to a report: but I get an error (The report has no tables)
Dim sqlConn As String = "SELECT (SUM(item_selldetail * item_quantity )/ 100 * 12) AS isv_report," & _
" (SUM( item_selldetail * item_quantity ) - (SUM(item_selldetail * item_quantity )/ 100 * 12)) " & _
" AS capital_report,SUM( item_selldetail * item_quantity ) AS total_report FROM qa_items;"
Dim objDataAdapter As New MySqlDataAdapter(sqlConn, objConn)
' DataSet
Dim ds As New DataSet
' llenar el DataSet
objDataAdapter.Fill(ds)
Dim mireporte As New ReportDocument()
mireporte.Load("C:\Users\Jonathan\Desktop\Proyectos\Quickadmon\Quickadmon\Reportes\report_capital_rpt.rpt")
mireporte.SetDataSource(ds)
Me.capitalreport_viewer_capital_report.ReportSource = mireporte
Anyone have any idea what I can do?
Sample code here , try to dolike this
sql = "SELECT Product_id,Product_name,Product_price FROM Product"
Dim dscmd As New SqlDataAdapter(sql, cnn)
Dim ds As New DataSet1
dscmd.Fill(ds, "Product")
cnn.Close()
Dim objRpt As New CrystalReport1
objRpt.SetDataSource(ds.Tables(1))
CrystalReportViewer1.ReportSource = objRpt
CrystalReportViewer1.Refresh()
If you need full source code :
http://vb.net-informations.com/crystal-report/crystal_report_from_sql_query_string.htm
merca.
Here's what I've done in the past.
1.) Create an ADO.NET (XML) Connection in Crystal. You will need to provide a path to an XML file to do this, the XML file will include the DataTable (or DataReader's) schema. It would look something like this (the x0020 represents a space in a field if you have one, see http://www.blakepell.com/Blog/?p=14 for more details on that):
<?xml version="1.0" encoding="utf-8" ?>
<people>
<first_x0020_name>
<last_x0020_name>
<phone>
</people>
2.) Set your data source like you did, in my wrapper code I had something like this where I was setting it from properties on the wrapper:
If _dataReader IsNot Nothing Then
report.SetDataSource(_dataReader)
End If
If _dataTable IsNot Nothing Then
report.SetDataSource(_dataTable)
End If
3.) Put it in your viewer control (or export it which is usually what I do since I'm generating the PDF output from it).
report.Export()
If this doesn't work for you, then post the specific stack trace and exception that you receive whenever you do this so we can troubleshoot it better. ;)

REXML parsing an XML in ruby

Folks,
I am using REXML for a sample XML file:
<Accounts title="This is the test title">
<Account name="frenchcustomer">
<username name = "frencu"/>
<password pw = "hello34"/>
<accountdn dn = "https://frenchcu.com/"/>
<exporttest name="basic">
<exportname name = "basicexport"/>
<exportterm term = "oldschool"/>
</exporttest>
</Account>
<Account name="britishcustomer">
<username name = "britishcu"/>
<password pw = "mellow34"/>
<accountdn dn = "https://britishcu.com/"/>
<exporttest name="existingsearch">
<exportname name = "largexpo"/>
<exportterm term = "greatschool"/>
</exporttest>
</Account>
</Accounts>
I am reading the XML like this:
#data = (REXML::Document.new file).root
#dataarr = ##testdata.elements.to_a("//Account")
Now I want to get the username of the frenchcustomer, so I tried this:
#dataarr[#name=fenchcustomer].elements["username"].attributes["name"]
this fails, I do not want to use the array index, for example
#dataarr[1].elements["username"].attributes["name"]
will work, but I don't want to do that, is there something that i m missing here. I want to use the array and get the username of the french user using the Account name.
Thanks a lot.
I recommend you to use XPath.
For the first match, you can use first method, for an array, just use match.
The code above returns the username for the Account "frenchcustomer" :
REXML::XPath.first(yourREXMLDocument, "//Account[#name='frenchcustomer']/username/#name").value
If you really want to use the array created with ##testdata.elements.to_a("//Account"), you could use find method :
french_cust_elt = the_array.find { |elt| elt.attributes['name'].eql?('frenchcustomer') }
french_username = french_cust_elt.elements["username"].attributes["name"]
puts #data.elements["//Account[#name='frenchcustomer']"]
.elements["username"]
.attributes["name"]
If you want to iterate over multiple identical names:
#data.elements.each("//Account[#name='frenchcustomer']") do |fc|
puts fc.elements["username"].attributes["name"]
end
I don't know what your ##testdata are, I tried with the following testcode:
require "rexml/document"
#data = (REXML::Document.new DATA).root
#dataarr = #data.elements.to_a("//Account")
# Works
p #dataarr[1].elements["username"].attributes["name"]
#Works not
#~ p #dataarr[#name='fenchcustomer'].elements["username"].attributes["name"]
##dataarr is an array
#dataarr.each{|acc|
next unless acc.attributes['name'] =='frenchcustomer'
p acc.elements["username"].attributes["name"]
}
##dataarr is an array
puts "===Array#each"
#dataarr.each{|acc|
next unless acc.attributes['name'] =='frenchcustomer'
p acc.elements["username"].attributes["name"]
}
puts "===XPATH"
#data.elements.to_a("//Account[#name='frenchcustomer']").each{|acc|
p acc.elements["username"].attributes["name"]
}
__END__
<Accounts title="This is the test title">
<Account name="frenchcustomer">
<username name = "frencu"/>
<password pw = "hello34"/>
<accountdn dn = "https://frenchcu.com/"/>
<exporttest name="basic">
<exportname name = "basicexport"/>
<exportterm term = "oldschool"/>
</exporttest>
</Account>
<Account name="britishcustomer">
<username name = "britishcu"/>
<password pw = "mellow34"/>
<accountdn dn = "https://britishcu.com/"/>
<exporttest name="existingsearch">
<exportname name = "largexpo"/>
<exportterm term = "greatschool"/>
</exporttest>
</Account>
</Accounts>
I'm not very familiar with rexml, so I expect there is a better solution. But perhaps aomebody can take my code to build a better solution.

Resources