Issue setting DocumentElement - vb.net

I'm trying to set documentelement to what I want to be the root element. When i try to do so I get the following error
Property 'DocumentElement' is readonly. I suppose that makes sense. I'm currently trying to convert msxml to system.xml.
Public Function GetXmlAllHierarchyObjects(Optional ByVal blnHideDisabled As Boolean = False) As XmlDocument
Dim recHierarchy As Recordset
Dim strSql As String = ""
Dim xmlDoc As XmlDocument = New XmlDocument()
Dim xmlRoot As XmlElement
Dim xmlParent As XmlNode
Dim intHeight As Integer
Dim xmlHierarchy As XmlElement
xmlRoot = xmlDoc.CreateElement("Hierarchy")
xmlDoc.DocumentElement = xmlRoot ' Error occurs here
recHierarchy = GetAllHierarchyObjects(blnHideDisabled, True)
Do While Not recHierarchy.EOF
xmlParent = xmlDoc.selectSingleNode("//Object[#ID='" & CStrSafe(recHierarchy("ParentID")) & "']")
If xmlParent Is Nothing Then
xmlParent = xmlRoot
intHeight = 0
Else
intHeight = CIntSafe(xmlParent.SelectSingleNode("Height").InnerText) + 1
End If
xmlHierarchy = xmlDoc.createElement("Object")
xmlParent.appendChild(xmlHierarchy)
xmlHierarchy.SetAttribute("ID", recHierarchy("ObjectID").ToString())
xmlHierarchy.appendChild(xmlDoc.createElement("Height"))
xmlHierarchy.LastChild.InnerText = CStrSafe(intHeight)
xmlHierarchy.appendChild(xmlDoc.createElement("ParentID"))
xmlHierarchy.LastChild.InnerText = CStrSafe(recHierarchy("ParentID"))
xmlHierarchy.appendChild(xmlDoc.createElement("Name"))
xmlHierarchy.LastChild.InnerText = CStrSafe(recHierarchy("Name"))
recHierarchy.MoveNext()
Loop
CloseRecordset(recHierarchy)
GetXmlAllHierarchyObjects = xmlDoc
End Function

The document element isn't really the root node. It's a level above the root. So you add your root node as a child of this.
Dim xmlDoc As XmlDocument = New XmlDocument()
Dim xmlRoot As XmlElement = xmlDoc.CreateElement("Hierarchy")
xmlDoc.AppendChild(xmlRoot)
MsgBox(xmlDoc.OuterXml)

Related

Receive object reference error when iterate the xdocument to retrieve xml element value

Dim lstrReadXml As String = String.Empty
mobjComFun.ReadTextFile(System.Windows.Forms.Application.StartupPath & "\GoFirstBookingXML\GetBookRes.xml", lstrReadXml)
Dim lobjXdoc As XDocument = XDocument.Parse(lstrReadXml)
Dim lobjNs As New XmlNamespaceManager(lobjXdoc.CreateReader.NameTable)
lobjNs.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/")
lobjNs.AddNamespace("sc", "http://schemas.navitaire.com/WebServices/ServiceContracts/BookingService")
lobjNs.AddNamespace("dc", "http://schemas.navitaire.com/WebServices/DataContracts/Booking")
lobjNs.AddNamespace("a", "http://schemas.navitaire.com/WebServices/DataContracts/Common")
Dim lstrErrorMsg = String.Empty, lstrQueryStr As String = String.Empty
Dim lstrPaxNames As New StringBuilder
'Dim lstrFirstName As String = mobjComFun.GetElementValue(lobjXdoc, "/s:Envelope/s:Body/sc:GetBookingResponse/dc:Booking/dc:Passengers/dc:Passenger/dc:Names", lobjNs, lstrErrorMsg)
For Each lobXnode In lobjXdoc.XPathSelectElements("/s:Envelope/s:Body/sc:GetBookingResponse/dc:Booking/dc:Passengers/dc:Passenger", lobjNs)
If Not lobXnode Is Nothing Then
Dim lobjIEnum As IEnumerable(Of XElement) = From Nam In lobXnode.Elements(lobjNs. & "Names")
Select Nam
Dim lstrLN As String = lobXnode.Document.Element("LastName").Value
lstrPaxNames.Append(lobXnode.XPathSelectElement("/dc:Names", lobjNs).Value)
lstrPaxNames.Append(lobXnode.XPathSelectElement("/dc:Names/dc:BookingName/dc:LastName", lobjNs).Value & "/")
lstrPaxNames.Append(lobXnode.XPathSelectElement("/dc:Names/dc:BookingName/dc:FirstName", lobjNs).Value & " Y58TWL ")
End If
Next
When trying to foreach iterate the XDocument, I receive the object reference error when trying to get the element value inside the iteration.

VB.Net signedXml "Invalid character in a Base-64 string"

I'm getting an error everytime I try to upload a XML file to an specific server.
It returns "Invalid character in a Base-64 string". Here the code I'm using to sign:
Public Sub Assinar03(ByVal strArqXMLAssinar As String, ByVal strUri As String, ByVal x509Certificado As X509Certificate2, ByVal strArqXMLAssinado As String)
Dim SR As StreamReader = Nothing
SR = File.OpenText(strArqXMLAssinar)
Dim vXMLString As String = SR.ReadToEnd()
SR.Close()
Dim _xnome As String = String.Empty
Dim _serial As String = String.Empty
If x509Certificado IsNot Nothing Then
_xnome = x509Certificado.Subject.ToString()
_serial = x509Certificado.SerialNumber
End If
Dim _X509Cert As New X509Certificate2()
Dim store As New X509Store("MY", StoreLocation.CurrentUser)
store.Open(OpenFlags.[ReadOnly] Or OpenFlags.OpenExistingOnly)
Dim collection As X509Certificate2Collection = DirectCast(store.Certificates, X509Certificate2Collection)
Dim collection1 As X509Certificate2Collection = DirectCast(collection.Find(X509FindType.FindBySerialNumber, _serial, False), X509Certificate2Collection)
If collection1.Count > 0 Then
_X509Cert = Nothing
For i As Integer = 0 To collection1.Count - 1
If DateTime.Now < collection1(i).NotAfter OrElse Not _X509Cert Is Nothing AndAlso _X509Cert.NotAfter < collection1(i).NotAfter Then
_X509Cert = collection1(i)
End If
Next
If _X509Cert Is Nothing Then _X509Cert = collection1(0)
Dim doc As New XmlDocument()
doc.PreserveWhitespace = False
doc.LoadXml(vXMLString)
Dim qtdeRefUri As Integer = doc.GetElementsByTagName(strUri).Count
Dim reference As New Reference()
Dim keyInfo As New KeyInfo()
Dim signedXml As New SignedXml(doc)
signedXml.SigningKey = _X509Cert.PrivateKey
Dim _Uri As XmlAttributeCollection = doc.GetElementsByTagName(strUri).Item(0).Attributes
For Each _atributo As XmlAttribute In _Uri
If _atributo.Name.ToLower.Trim = "Id".ToLower.Trim Then
reference.Uri = "#" + _atributo.InnerText
End If
Next
If reference.Uri Is Nothing Then reference.Uri = ""
reference.DigestMethod = SignedXml.XmlDsigSHA1Url
'--------------------------------------------------
Dim env As New XmlDsigEnvelopedSignatureTransform()
env.Algorithm = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
reference.AddTransform(env)
'--------------------------
Dim c14 As New XmlDsigC14NTransform(False)
c14.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
reference.AddTransform(c14)
'--------------------------
signedXml.AddReference(reference)
keyInfo.AddClause(New KeyInfoX509Data(_X509Cert))
'--------------------------
signedXml.KeyInfo = keyInfo
signedXml.ComputeSignature()
'--
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
XMLDoc = New XmlDocument()
XMLDoc.PreserveWhitespace = False
XMLDoc = doc
Me.vXMLStringAssinado = XMLDoc.OuterXml
'-----------
Dim SW_2 As StreamWriter = File.CreateText(strArqXMLAssinado)
SW_2.Write(Me.vXMLStringAssinado)
SW_2.Close()
'-----------
End If
SR.Close()
End Sub
Is there something else I should add to the code?
The manual tells me to follow the instructions from https://www.w3.org/TR/xmldsig-core/
Turns out it was a line break when saving the document. I set the .PreserveWhitespace property to true before saving the .xml file and not it seems to be working.

Programmatically adding/displaying/inserting images to OneNote 2013

I'm having trouble adding an image to a page in OneNote 2013. I can create sections, notebooks and pages with content, but I'm having trouble adding an image to the page.
I call UpdatePageContent and pass in the xml but I get an invalid XML message (hresult 0x80042001) back. Any assistance appreciated. Here is the complete code that I use to create an XML that I'm trying to update the page with:
Sub CreateNewPage(ByVal pageName As String)
Dim OneNote As Microsoft.Office.Interop.OneNote.Application
OneNote = New Microsoft.Office.Interop.OneNote.Application
' Get all of the Notebook nodes.
Dim nodes As MSXML2.IXMLDOMNodeList
nodes = GetFirstOneNoteNotebookNodes(oneNote)
If Not nodes Is Nothing Then
' Get the first OneNote Notebook in the XML document.
Dim node As MSXML2.IXMLDOMNode
node = nodes(0)
Dim noteBookName As String = ""
noteBookName = node.attributes.getNamedItem("name").text
' Get the ID for the Notebook so the code can retrieve
' the list of sections.
Dim notebookID As String
notebookID = node.attributes.getNamedItem("ID").text
' Load the XML for the Sections for the Notebook requested.
Dim sectionsXml As String = ""
oneNote.GetHierarchy(notebookID, Microsoft.Office.Interop.OneNote.HierarchyScope.hsSections, sectionsXml)
Dim secDoc As MSXML2.DOMDocument
secDoc = New MSXML2.DOMDocument
If secDoc.loadXML(sectionsXml) Then
' select the Section nodes
Dim secNodes As MSXML2.IXMLDOMNodeList
secNodes = secDoc.documentElement.selectNodes("//one:Section[#name='Balaji1']")
If Not secNodes Is Nothing Then
' Get the first section.
Dim secNode As MSXML2.IXMLDOMNode
secNode = secNodes(0)
Dim sectionName As String = ""
sectionName = secNode.attributes.getNamedItem("name").text
Dim sectionID As String
sectionID = secNode.attributes.getNamedItem("ID").text
Dim doc As MSXML2.DOMDocument
doc = New MSXML2.DOMDocument
'oneNote.GetHierarchy()
Dim sectionXML As String = ""
Dim newPageID As String = ""
sectionXML = ""
oneNote.GetHierarchy("", Microsoft.Office.Interop.OneNote.HierarchyScope.hsPages, sectionXML)
newPageID = GetPageIDByPageName(pageName, sectionXML)
' Create a new blank Page in the first Section
' using the default format.
If Len(newPageID) = 0 Then
oneNote.CreateNewPage(sectionID, newPageID, Microsoft.Office.Interop.OneNote.NewPageStyle.npsDefault)
End If
' Get the contents of the page.
Dim outXML As String = ""
oneNote.GetPageContent(newPageID, outXML, Microsoft.Office.Interop.OneNote.PageInfo.piAll)
' Load Page's XML into a MSXML2.DOMDocument object.
If doc.loadXML(outXML) Then
' Get Page Node.
Dim pageNode As MSXML2.IXMLDOMNode
pageNode = doc.selectSingleNode("//one:Page")
' Find the Title element.
Dim titleNode As MSXML2.IXMLDOMNode
titleNode = doc.selectSingleNode("//one:Page/one:Title/one:OE/one:T")
' Get the CDataSection where OneNote store's the Title's text.
Dim cdataChild As MSXML2.IXMLDOMNode
cdataChild = titleNode.selectSingleNode("text()")
'change the title will change the pageName
' Change the title in the local XML copy.
cdataChild.text = pageName
' Write the update to OneNote.
oneNote.UpdatePageContent(doc.xml)
Dim newElement As MSXML2.IXMLDOMElement
Dim newNode As MSXML2.IXMLDOMNode
' Create Outline node.
newElement = doc.createElement("one:Outline")
newNode = pageNode.appendChild(newElement)
' Create OEChildren.
newElement = doc.createElement("one:OEChildren")
newNode = newNode.appendChild(newElement)
' Create OE.
newElement = doc.createElement("one:OE")
newNode = newNode.appendChild(newElement)
' Create TE.
newElement = doc.createElement("one:T")
newNode = newNode.appendChild(newElement)
newElement = doc.createElement("one:Image")
newNode = newNode.appendChild(newElement)
' Add the text for the Page's content.
Dim cd As MSXML2.IXMLDOMCDATASection
cd = doc.createCDATASection("YOUR TEXT HERE")
newNode.appendChild(cd)
' Update OneNote with the new content.
oneNote.UpdatePageContent(doc.xml)
' Print out information about the update.
MsgBox("A new page was created in Section '" & sectionName & "' in Notebook '" & noteBookName & "'.")
Debug.Print(doc.xml)
End If
Else
MsgBox("OneNote 2010 Section nodes not found.")
End If
Else
MsgBox("OneNote 2010 Section XML Data failed to load.")
End If
Else
MsgBox("OneNote 2010 XML Data failed to load.")
End If
End Sub

Parse a xml file in Visual basic

which is the best way to parse this xml ???
<?xml version="1.0" encoding="UTF-8"?>
<DOCWARE Version="1.1">
<Order Count="2">
<Pos0>
<M_TEXTNR>sAuspuffendrohr</M_TEXTNR>
<VM_BESTNR>s02010000373</VM_BESTNR>
<P_PREIS>s715.80</P_PREIS>
</Pos0>
<Pos1>
<M_TEXTNR>sMutter</M_TEXTNR>
<VM_BESTNR>s02010000373</VM_BESTNR>
<P_PREIS>s0.70</P_PREIS>
</Pos1>
</Order>
<TotalSum>s</TotalSum>
</DOCWARE>
I Try to do so, but is not working then i = 1
Dim xmldoc As New XmlDataDocument()
Dim xmlnode As XmlNodeList
Dim fs As New FileStream(myFileName, FileMode.Open, FileAccess.Read)
xmldoc.Load(fs)
For i As Integer = 0 To 1
xmlnode = xmldoc.GetElementsByTagName("Pos" & i)
dim val as string = xmlnode(i).ChildNodes.Item(0).InnerText.Trim()
MsgBox(val)
Next
thanks in advance
To read a tag with a changed name you can to do using xmlReader and find if you document.Name contains this prefix "Pos", try to use this code:
Dim document As XmlReader = New XmlTextReader(fileName)
While (document.Read())
Dim type = document.NodeType
If (type = XmlNodeType.Element) Then
If (document.Name.Contains("Pos")) Then
Dim test As String = document.ReadInnerXml.ToString()
Dim doc As New XmlDocument()
doc.LoadXml("<Pos>" & test & "</Pos>")
Dim root As XmlNode = doc.FirstChild
If root.HasChildNodes Then
dim _value = root.ChildNodes.Item(0).InnerText.Trim()
End If
End If
End If
End While

How to extract Atom/RSS

Given a URL, if it has any RSS nodes, then I am adding to the database.
e.g.:
For this URL, rssDoc.SelectNodes("rss/channel/item").Count is greater than zero.
But for the atom url, rssDoc.SelectNodes("rss/channel/item").count is equal to zero.
How can I check if the Atom/RSS URL has any nodes or not? I have tried for rssDoc.SelectNodes("feed/entry").Count, but is giving me zero count.
Public Shared Function HasRssItems(ByVal url as string) As Boolean
Dim myRequest As WebRequest
Dim myResponse As WebResponse
Try
myRequest = System.Net.WebRequest.Create(url)
myRequest.Timeout = 5000
myResponse = myRequest.GetResponse()
Dim rssStream As Stream = myResponse.GetResponseStream()
Dim rssDoc As New XmlDocument()
rssDoc.Load(rssStream)
Return rssDoc.SelectNodes("rss/channel/item").Count > 0
Catch ex As Exception
Return False
Finally
myResponse.Close()
End Try
End Function
Your main problem here is that the XML "node path" on this line:
Return rssDoc.SelectNodes("rss/channel/item").Count > 0
is only valid for RSS feeds, not ATOM feeds.
One way I've got over this in the past is to use a simple function to convert an ATOM feed into an RSS feed. Of course, you could go the other way, or not convert at all, however, converting to a single format enables you to write one "generic" chunk of code that will pull out the various elements of a feed's items that you may be interested in (i.e. date, title etc.)
There is an ATOM to RSS Converter article on Code Project that provides such a conversion, however, that is in C#. I have previously manually converted this to VB.NET myself, so here's the VB.NET version:
Private Function AtomToRssConverter(ByVal atomDoc As XmlDocument) As XmlDocument
Dim xmlDoc As XmlDocument = atomDoc
Dim xmlNode As XmlNode = Nothing
Dim mgr As New XmlNamespaceManager(xmlDoc.NameTable)
mgr.AddNamespace("atom", "http://purl.org/atom/ns#")
Const rssVersion As String = "2.0"
Const rssLanguage As String = "en-US"
Dim rssGenerator As String = "RDFFeedConverter"
Dim memoryStream As New MemoryStream()
Dim xmlWriter As New XmlTextWriter(memoryStream, Nothing)
xmlWriter.Formatting = Formatting.Indented
Dim feedTitle As String = ""
Dim feedLink As String = ""
Dim rssDescription As String = ""
xmlNode = xmlDoc.SelectSingleNode("//atom:title", mgr)
If xmlNode Is Nothing Then
This looks like an ATOM v1.0 format, rather than ATOM v0.3.
mgr.RemoveNamespace("atom", "http://purl.org/atom/ns#")
mgr.AddNamespace("atom", "http://www.w3.org/2005/Atom")
End If
xmlNode = xmlDoc.SelectSingleNode("//atom:title", mgr)
If Not xmlNode Is Nothing Then
feedTitle = xmlNode.InnerText
End If
xmlNode = xmlDoc.SelectNodes("//atom:link/#href", mgr)(2)
If Not xmlNode Is Nothing Then
feedLink = xmlNode.InnerText
End If
xmlNode = xmlDoc.SelectSingleNode("//atom:tagline", mgr)
If Not xmlNode Is Nothing Then
rssDescription = xmlNode.InnerText
End If
xmlNode = xmlDoc.SelectSingleNode("//atom:subtitle", mgr)
If Not xmlNode Is Nothing Then
rssDescription = xmlNode.InnerText
End If
xmlWriter.WriteStartElement("rss")
xmlWriter.WriteAttributeString("version", rssVersion)
xmlWriter.WriteStartElement("channel")
xmlWriter.WriteElementString("title", feedTitle)
xmlWriter.WriteElementString("link", feedLink)
xmlWriter.WriteElementString("description", rssDescription)
xmlWriter.WriteElementString("language", rssLanguage)
xmlWriter.WriteElementString("generator", rssGenerator)
Dim items As XmlNodeList = xmlDoc.SelectNodes("//atom:entry", mgr)
If items Is Nothing Then
Throw New FormatException("Atom feed is not in expected format. ")
Else
Dim title As String = [String].Empty
Dim link As String = [String].Empty
Dim description As String = [String].Empty
Dim author As String = [String].Empty
Dim pubDate As String = [String].Empty
For i As Integer = 0 To items.Count - 1
Dim nodTitle As XmlNode = items(i)
xmlNode = nodTitle.SelectSingleNode("atom:title", mgr)
If Not xmlNode Is Nothing Then
title = xmlNode.InnerText
End If
Try
link = items(i).SelectSingleNode("atom:link[#rel= alternate ]", mgr).Attributes("href").InnerText
Catch ex As Exception
link = items(i).SelectSingleNode("atom:link", mgr).Attributes("href").InnerText
End Try
xmlNode = items(i).SelectSingleNode("atom:content", mgr)
If Not xmlNode Is Nothing Then
description = xmlNode.InnerText
End If
xmlNode = items(i).SelectSingleNode("//atom:name", mgr)
If Not xmlNode Is Nothing Then
author = xmlNode.InnerText
End If
xmlNode = items(i).SelectSingleNode("atom:issued", mgr)
If Not xmlNode Is Nothing Then
pubDate = xmlNode.InnerText
End If
xmlNode = items(i).SelectSingleNode("atom:updated", mgr)
If Not xmlNode Is Nothing Then
pubDate = xmlNode.InnerText
End If
xmlWriter.WriteStartElement("item")
xmlWriter.WriteElementString("title", title)
xmlWriter.WriteElementString("link", link)
If pubDate.Length < 1 Then
pubDate = Date.MinValue.ToString()
End If
xmlWriter.WriteElementString("pubDate", Convert.ToDateTime(pubDate).ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss G\MT"))
xmlWriter.WriteElementString("author", author)
xmlWriter.WriteElementString("description", description)
xmlWriter.WriteEndElement()
Next
xmlWriter.WriteEndElement()
xmlWriter.Flush()
xmlWriter.Close()
End If
Dim retDoc As New XmlDocument()
Dim outStr As String = Encoding.UTF8.GetString(memoryStream.ToArray())
retDoc.LoadXml(outStr)
Return retDoc
End Function
Usage is fairly straight forward. Simply load in your ATOM feed into an XmlDocument object and pass it to this function, and you'll get an XmlDocument object back, in RSS format!
If you're interested, I've put an entire RSSReader class up on pastebin.com