Select node in youtube feed response using xpath in vb6 - xpath

for each entry in this xml, i need to get the "title" and the first thumbnail image. that is the first image in the media:group
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/'>
<entry>
<title>Progression! 9 more pounds to goo!</title>
<media:group>
<media:thumbnail url='http://i.ytimg.com/vi/7MTjYXt3rLQ/default.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/7MTjYXt3rLQ/mqdefault.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/7MTjYXt3rLQ/hqdefault.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/7MTjYXt3rLQ/1.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/7MTjYXt3rLQ/2.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/7MTjYXt3rLQ/3.jpg'/>
</media:group>
</entry>
<entry>
<title>Plank Variations Workout with Max Wettstein</title>
<media:group>
<media:thumbnail url='http://i.ytimg.com/vi/O1Nd8lZFGpc/default.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/O1Nd8lZFGpc/mqdefault.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/O1Nd8lZFGpc/hqdefault.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/O1Nd8lZFGpc/1.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/O1Nd8lZFGpc/2.jpg'/>
<media:thumbnail url='http://i.ytimg.com/vi/O1Nd8lZFGpc/3.jpg'/>
</media:group>
</entry>
</feed>
this is my code
Dim xmlDoc As MSXML2.DOMDocument30
Dim xmlEntryNode As MSXML2.IXMLDOMNode
Dim xmlEntryNodes As IXMLDOMNodeList
Dim xmlC1Nodes As IXMLDOMNodeList
Dim ns As String
Set xmlDoc = New DOMDocument30
ns = txtNS.Text
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.setProperty "SelectionNamespaces", ns
If xmlDoc.loadXML(txtXml.Text) = False Then
appendText "xml document load failed"
Exit Sub
End If
Set xmlEntryNodes = xmlDoc.documentElement.selectNodes(/x:feed/x:entry)
Dim i As Integer
For i = 0 To xmlEntryNodes.length - 1
Set xmlEntryNode = xmlEntryNodes(i)
appendText xmlEntryNode.Text
Set xmlC1Nodes = xmlDoc.selectNodes(//media:group/media:thumbnail[1]/#url)
If xmlC1Nodes.length > 0 Then
Dim j As Integer
For j = 0 To xmlC1Nodes.length - 1
appendText xmlC1Nodes(j).Text
Next
End If
Next
Exit Sub
and here is my output
Progression! 9 more pounds to goo!
http://i.ytimg.com/vi/7MTjYXt3rLQ/default.jpg
http://i.ytimg.com/vi/O1Nd8lZFGpc/default.jpg Plank Variations
Workout with Max Wettstein
http://i.ytimg.com/vi/7MTjYXt3rLQ/default.jpg
http://i.ytimg.com/vi/O1Nd8lZFGpc/default.jpg
can anyone pls help me adjust to make it return only one image for each entry

I'm not well-versed in VB6, but coming at this from an XPath point of view, I would select relative to the xmlEntryNode you've already got:
Set xmlC1Nodes = xmlEntryNode.selectNodes("media:group/media:thumbnail[1]/#url")
(I don't understand why your XPath expression isn't in quotes... But you said it produces output...)
Or if the selectNodes() method only applies to XML documents, then
Set xmlC1Nodes = xmlDoc.selectNodes(
"/*/x:entry[" + i + "]/media:group/media:thumbnail[1]/#url")

can anyone pls help me adjust to make it return only one image for each entry
Use something like this (Haven't used MSXML or VB since many years):
Set urlAttrib = xmlEntryNode.SelectSingleNode("media:group/media:thumbnail[1]/#url")
wantedText = urlAttrib.nodeValue

Related

How to combine two XML files with Nokogiri

I am trying to combine two separate, but related, files with Nokogiri. I want to combine the "product" and "product pricing" if "ItemNumber" is the same.
I loaded the documents, but I have no idea how to combine the two.
Product File:
<Products>
<Product>
<Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name>
<ProductTypeId>0</ProductTypeId>
<Description>This single bit curved grip axe handle is made for 3 to 5 pound axes. A good quality replacement handle made of American hickory with a natural wax finish. Hardwood handles do not conduct electricity and American Hickory is known for its strength, elasticity and ability to absorb shock. These handles provide exceptional value and economy for homeowners and other occasional use applications. Each Link handle comes with the required wedges, rivets, or epoxy needed for proper application of the tool head.</Description>
<ActiveFlag>Y</ActiveFlag>
<ImageFile>100024.jpg</ImageFile>
<ItemNumber>100024</ItemNumber>
<ProductVariants>
<ProductVariant>
<Sku>100024</Sku>
<ColorName></ColorName>
<SizeName></SizeName>
<SequenceNo>0</SequenceNo>
<BackOrderableFlag>N</BackOrderableFlag>
<InventoryLevel>0</InventoryLevel>
<ColorCode></ColorCode>
<SizeCode></SizeCode>
<TaxableFlag>Y</TaxableFlag>
<VariantPromoGroupCode></VariantPromoGroupCode>
<PricingGroupCode></PricingGroupCode>
<StartDate xsi:nil="true"></StartDate>
<EndDate xsi:nil="true"></EndDate>
<ActiveFlag>Y</ActiveFlag>
</ProductVariant>
</ProductVariants>
</Product>
</Products>
Product Pricing Fields:
<ProductPricing>
<ItemNumber>100024</ItemNumber>
<AcquisitionCost>8.52</AcquisitionCost>
<MemberCost>10.7</MemberCost>
<Price>14.99</Price>
<SalePrice xsi:nil="true"></SalePrice>
<SaleCode>0</SaleCode>
</ProductPricing>
I am looking to generate a file like this:
<Products>
<Product>
<Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name>
<ProductTypeId>0</ProductTypeId>
<Description>This single bit curved grip axe handle is made for 3 to 5 pound axes. A good quality replacement handle made of American hickory with a natural wax finish. Hardwood handles do not conduct electricity and American Hickory is known for its strength, elasticity and ability to absorb shock. These handles provide exceptional value and economy for homeowners and other occasional use applications. Each Link handle comes with the required wedges, rivets, or epoxy needed for proper application of the tool head.</Description>
<ActiveFlag>Y</ActiveFlag>
<ImageFile>100024.jpg</ImageFile>
<ItemNumber>100024</ItemNumber>
<ProductVariants>
<ProductVariant>
<Sku>100024</Sku>
<ColorName></ColorName>
<SizeName></SizeName>
<SequenceNo>0</SequenceNo>
<BackOrderableFlag>N</BackOrderableFlag>
<InventoryLevel>0</InventoryLevel>
<ColorCode></ColorCode>
<SizeCode></SizeCode>
<TaxableFlag>Y</TaxableFlag>
<VariantPromoGroupCode></VariantPromoGroupCode>
<PricingGroupCode></PricingGroupCode>
<StartDate xsi:nil="true"></StartDate>
<EndDate xsi:nil="true"></EndDate>
<ActiveFlag>Y</ActiveFlag>
</ProductVariant>
</ProductVariants>
</Product>
<ProductPricing>
<ItemNumber>100024</ItemNumber>
<AcquisitionCost>8.52</AcquisitionCost>
<MemberCost>10.7</MemberCost>
<Price>14.99</Price>
<SalePrice xsi:nil="true"></SalePrice>
<SaleCode>0</SaleCode>
</ProductPricing>
</Products>
Here is the code I have so far:
require 'csv'
require 'nokogiri'
xml = File.read('lateApril-product-pricing.xml')
xml2 = File.read('lateApril-master-date')
doc = Nokogiri::XML(xml)
doc2 = Nokogiri::XML(xml2)
pricing_data = []
item_number = []
doc.xpath('//ProductsPricing/ProductPricing').each do |file|
itemNumber = file.xpath('./ItemNumber').first.text
variant_Price = file.xpath('./Price').first.text
pricing_data << [ itemNumber, variant_Price ]
item_number << [ itemNumber ]
end
puts item_number ## This prints all the item number but i have no idea how to loop through them and combine them with Product XML
doc2.xpath('//Products/Product').each do |file|
itemNumber = file.xpath('./ItemNumber').first.text #not sure how to write the conditions here since i don't have pricing fields available in this method
end
Try this on:
require 'nokogiri'
doc1 = Nokogiri::XML(<<EOT)
<Products>
<Product>
<Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name>
</Product>
</Products>
EOT
doc2 = Nokogiri::XML(<<EOT)
<ProductPricing>
<ItemNumber>100024</ItemNumber>
</ProductPricing>
EOT
doc1.at('Product').add_next_sibling(doc2.at('ProductPricing'))
Which results in:
puts doc1.to_xml
# >> <?xml version="1.0"?>
# >> <Products>
# >> <Product>
# >> <Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name>
# >> </Product><ProductPricing>
# >> <ItemNumber>100024</ItemNumber>
# >> </ProductPricing>
# >> </Products>
Please, when you ask, strip the example input and expected resulting output to the absolute, bare, minimum. Anything beyond that wastes space, eye-time and brain CPU.
This is untested code, but is where I'd start if I was going to merge two files containing multiple <ItemNumber> nodes:
require 'nokogiri'
doc1 = Nokogiri::XML(<<EOT)
<Products>
<Product>
<Name>36-In. Homeowner Bent Single-Bit Axe Handle</Name>
<ItemNumber>100024</ItemNumber>
</Product>
</Products>
EOT
doc2 = Nokogiri::XML(<<EOT)
<ProductPricing>
<ItemNumber>100024</ItemNumber>
</ProductPricing>
EOT
# build a hash containing the item numbers in doc1 for each product
doc1_products_by_item_numbers = doc1.search('Product').map { |product|
item_number = product.at('ItemNumber').value
[
item_number,
product
]
}.to_hash
# build a hash containing the item numbers in doc2 for each product pricing
doc2_products_by_item_numbers = doc2.search('ProductPricing').map { |pricing|
item_number = pricing.at('ItemNumber').value
[
item_number,
pricing
]
}.to_hash
# append doc2 entries to doc1 after each product based on item numbers
doc1_products_by_item_numbers.keys.each { |k|
doc1_products_by_item_numbers[k].add_next_sibling(doc2_products_by_item_numbers[k])
}

? How to obtain tags by part of element name

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)

VB Script for Automating File Creation (On-Demand Opportunity!)

I'm a Financial person and not quite the VB scripting guru, but I'm wondering if someone could create a sample vb script based on my requirements.
Whoever provides the solution first and the solution works on my end will have an opportunity (paid of course) to create more of these custom solutions where I work at. It wouldn't be full-time position, but more of an On-Demand opportunity.
Requirements:
To be able to read a text file that is delimited by comma and has various entries
For example, in text file...
SEC_E_All_Entities,HSII,SL_DIMENSION,READWRITE,#IDESCENDANTS,N
SEC_E_ENT_Americas,Americas,SL_DIMENSION,READ,MEMBER,N
And perform the following...
Create an XML file per entry, based on the first value
For example:
Create SEC_E_All_Entities.XML and SEC_E_ENT_Americas.XML
Within each file, write the contents where you can see how the values match each tag.
For example:
In the SEC_E_All_Entities.XML file, write...
<?xml version="1.0" encoding="UTF-8" ?>
<acls>
<acl>
<name>SEC_E_All_Entities</name>
<objectName>HSII</objectName>
<objectType>SL_DIMENSION</objectType>
<accessMode>READWRITE</accessMode>
<flag>#IDESCENDANTS</flag>
<isUser>N</isUser>
</acl>
</acls>
In the SEC_E_All_Americas.XML file, write...
<?xml version="1.0" encoding="UTF-8" ?>
<acls>
<acl>
<name>SEC_E_ENT_Americas</name>
<objectName>Americas</objectName>
<objectType>SL_DIMENSION</objectType>
<accessMode>READ</accessMode>
<flag>MEMBER</flag>
<isUser>N</isUser>
</acl>
</acls>
Regards,
Judy
Sample script
'Step 1 - Read the file and store the content in memory (an array)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Users\pankaj.jaju\Desktop\StackOverflow\acls.txt", 1)
arrFile = Split(objFile.ReadAll, vbCrLf) 'will store one line in each array index
objFile.Close
'Step 2 - Load the XML template in memory
Set xmlTemplate = CreateObject("MSXML2.DOMDocument.6.0")
With xmlTemplate
.ValidateOnParse = True
.Async = False
.LoadXML "<?xml version=""1.0"" encoding=""UTF-8"" ?>" & _
"<acls>" & _
"<acl>" & _
"<name></name>" & _
"<objectName></objectName>" & _
"<objectType></objectType>" & _
"<accessMode></accessMode>" & _
"<flag></flag>" & _
"<isUser></isUser>" & _
"</acl>" & _
"</acls>"
End With
'Step 3 - Load the relevant fields for which the data is to be set from csv file
Set nodeFields = xmlTemplate.DocumentElement.SelectNodes("/acls/acl/*")
'Step 4 - Read each line of text and create XML
For i = LBound(arrFile) To UBound(arrFile)
arrLine = Split(arrFile(i), ",") 'will split the line into various fields (to be used to create the xml)
For j = LBound(arrLine) To UBound(arrLine) 'set values for each field
nodeFields(j).Text = arrLine(j)
Next
Set xmlNew = xmlTemplate
xmlNew.Save objFSO.BuildPath("C:\Users\pankaj.jaju\Desktop\StackOverflow\", nodeFields(0).Text & ".xml") 'copy modified template as new xml file
Set xmlNew = Nothing
Next

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"

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. ;)

Resources