我一直在努力研究如何让这项工作工作几天(我已经结束了再次观看相同文章的循环,因为你已经搜索了这么多组合问题)
我看过Read XML in VB.net 和How to read an XML File以及How to read XML elements in VB.NET和Retrieve single attribute value from an xml doc element其中最后一个似乎指向了我关于正确方向的回合,但在运行DWRoelands指定的代码后,我收到了"系统.Collections.Generic.List`1 [System.String]"到控制台输出。
请参阅下面的XML,我需要从/ Files / File / Link元素中的HREF属性中提取https://server/transfer/descriptor.ovf,并且仅针对作为descriptor.ovf列出的文件提取{我运行此文件的第二个XML文件另一个为VMDK列出的文件)
由于
XML片段:
<?xml version="1.0" encoding="UTF-8"?>
<VApp href="https://#####/api/vApp/vapp-##">
<Link rel="down"/>
<Description>Test vAPP</Description>
<Tasks>
<Task cancelRequested="false" >
<Link rel="task:cancel" />
<Progress>1</Progress>
<Details/>
</Task>
</Tasks>
<Files>
<File bytesTransferred="0" size="-1" name="descriptor.ovf">
<Link rel="upload:default" href="https://server/transfer/descriptor.ovf"/>
</File>
</Files>
<InMaintenanceMode>false</InMaintenanceMode>
</VApp>
&#13;
整个XML:
<?xml version="1.0" encoding="UTF-8"?>
<VApp xmlns="http://www.vmware.com/vcloud/v1.5" ovfDescriptorUploaded="false" deployed="false" status="0" name="Test vAPP" id="urn:vcloud:vapp:#####" href="https://server/api/vApp/vapp-#####" type="application/vnd.vmware.vcloud.vApp+xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 https://server/api/v1.5/schema/master.xsd">
<Link rel="down" href="https://server/api/vApp/vapp-#####/controlAccess/" type="application/vnd.vmware.vcloud.controlAccess+xml"/>
<Link rel="up" href="https://server/api/vdc/#####" type="application/vnd.vmware.vcloud.vdc+xml"/>
<Link rel="down" href="https://server/api/vApp/vapp-#####/owner" type="application/vnd.vmware.vcloud.owner+xml"/>
<Link rel="down" href="https://server/api/vApp/vapp-#####/metadata" type="application/vnd.vmware.vcloud.metadata+xml"/>
<Link rel="ovf" href="https://server/api/vApp/vapp-#####/ovf" type="text/xml"/>
<Link rel="down" href="https://server/api/vApp/vapp-#####/productSections/" type="application/vnd.vmware.vcloud.productSections+xml"/>
<Description>Test vAPP</Description>
<Tasks>
<Task cancelRequested="false" expiryTime="2017-07-30T11:02:07.457+08:00" operation="Importing Virtual Application Test vAPP(#####)" operationName="vdcUploadOvfContents" serviceNamespace="com.vmware.vcloud" startTime="2017-05-01T11:02:07.457+08:00" status="running" name="task" id="urn:vcloud:task:######" href="https://server/api/task/####" type="application/vnd.vmware.vcloud.task+xml">
<Link rel="task:cancel" href="https://server/api/task/#####/action/cancel"/>
<Owner href="https://server/api/vApp/vapp-#####" name="Test vAPP" type="application/vnd.vmware.vcloud.vApp+xml"/>
<User href="https://server/api/admin/user/####" name="#####" type="application/vnd.vmware.admin.user+xml"/>
<Organization href="https://server/api/org/#####" name="#####" type="application/vnd.vmware.vcloud.org+xml"/>
<Progress>1</Progress>
<Details/>
</Task>
</Tasks>
<Files>
<File bytesTransferred="0" size="-1" name="descriptor.ovf">
<Link rel="upload:default" href="https://server/transfer/#####/descriptor.ovf"/>
</File>
</Files>
<DateCreated>2017-05-01T11:02:07.417+08:00</DateCreated>
<Owner type="application/vnd.vmware.vcloud.owner+xml">
<User href="https://server/api/admin/user/#####" name="#####" type="application/vnd.vmware.admin.user+xml"/>
</Owner>
<InMaintenanceMode>false</InMaintenanceMode>
</VApp>
&#13;
答案 0 :(得分:0)
首先加载文件,如果使用XElement,则可以使用文字进行测试。
'Dim yourpath As String = "your path here"
Dim xe As XElement
'to load from a file
'xe = XElement.Load(yourpath)
'for testing
xe = <VApp href="https://#####/api/vApp/vapp-##">
<Link rel="down"/>
<Description>Test vAPP</Description>
<Tasks>
<Task cancelRequested="false">
<Link rel="task:cancel"/>
<Progress>1</Progress>
<Details/>
</Task>
</Tasks>
<Files>
<File bytesTransferred="0" size="-1" name="descriptor.ovf">
<Link rel="upload:default" href="https://server/transfer/descriptor.ovf"/>
</File>
</Files>
<InMaintenanceMode>false</InMaintenanceMode>
</VApp>
' to save file
' xe.Save(yourpath)
现在加载它很容易选择你想要的元素
<强>编辑强>
Dim dovf As IEnumerable = (From el In xe...<Files>
Where el.<File>.@name = "descriptor.ovf"
Select el.<File>.<Link>.@href)
For Each s As String In dovf
Stop
Next
基于上面的整个xml示例,我不得不将其添加为程序的第一行
Imports <xmlns="http://www.vmware.com/vcloud/v1.5">
答案 1 :(得分:0)
Paste your xml as classes with Visual Studio。确保任何xml数组都有多个项目,以便正确生成模式。这是我的结果:
'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True), _
System.Xml.Serialization.XmlRootAttribute([Namespace]:="", IsNullable:=False)> _
Partial Public Class VApp
Private linkField As VAppLink
Private descriptionField As String
Private tasksField() As VAppTask
Private filesField() As VAppFile
Private inMaintenanceModeField As Boolean
Private hrefField As String
'''<remarks/>
Public Property Link() As VAppLink
Get
Return Me.linkField
End Get
Set(value As VAppLink)
Me.linkField = value
End Set
End Property
'''<remarks/>
Public Property Description() As String
Get
Return Me.descriptionField
End Get
Set(value As String)
Me.descriptionField = value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlArrayItemAttribute("Task", IsNullable:=False)> _
Public Property Tasks() As VAppTask()
Get
Return Me.tasksField
End Get
Set(value As VAppTask())
Me.tasksField = value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlArrayItemAttribute("File", IsNullable:=False)> _
Public Property Files() As VAppFile()
Get
Return Me.filesField
End Get
Set(value As VAppFile())
Me.filesField = value
End Set
End Property
'''<remarks/>
Public Property InMaintenanceMode() As Boolean
Get
Return Me.inMaintenanceModeField
End Get
Set(value As Boolean)
Me.inMaintenanceModeField = value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property href() As String
Get
Return Me.hrefField
End Get
Set(value As String)
Me.hrefField = value
End Set
End Property
End Class
'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)> _
Partial Public Class VAppLink
Private relField As String
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property rel() As String
Get
Return Me.relField
End Get
Set(value As String)
Me.relField = value
End Set
End Property
End Class
'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)> _
Partial Public Class VAppTask
Private linkField As VAppTaskLink
Private progressField As Byte
Private detailsField As Object
Private cancelRequestedField As Boolean
'''<remarks/>
Public Property Link() As VAppTaskLink
Get
Return Me.linkField
End Get
Set(value As VAppTaskLink)
Me.linkField = value
End Set
End Property
'''<remarks/>
Public Property Progress() As Byte
Get
Return Me.progressField
End Get
Set(value As Byte)
Me.progressField = value
End Set
End Property
'''<remarks/>
Public Property Details() As Object
Get
Return Me.detailsField
End Get
Set(value As Object)
Me.detailsField = value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property cancelRequested() As Boolean
Get
Return Me.cancelRequestedField
End Get
Set(value As Boolean)
Me.cancelRequestedField = value
End Set
End Property
End Class
'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)> _
Partial Public Class VAppTaskLink
Private relField As String
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property rel() As String
Get
Return Me.relField
End Get
Set(value As String)
Me.relField = value
End Set
End Property
End Class
'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)> _
Partial Public Class VAppFile
Private linkField As VAppFileLink
Private bytesTransferredField As Byte
Private sizeField As SByte
Private nameField As String
'''<remarks/>
Public Property Link() As VAppFileLink
Get
Return Me.linkField
End Get
Set(value As VAppFileLink)
Me.linkField = value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property bytesTransferred() As Byte
Get
Return Me.bytesTransferredField
End Get
Set(value As Byte)
Me.bytesTransferredField = value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property size() As SByte
Get
Return Me.sizeField
End Get
Set(value As SByte)
Me.sizeField = value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property name() As String
Get
Return Me.nameField
End Get
Set(value As String)
Me.nameField = value
End Set
End Property
End Class
'''<remarks/>
<System.Xml.Serialization.XmlTypeAttribute(AnonymousType:=True)> _
Partial Public Class VAppFileLink
Private relField As String
Private hrefField As String
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property rel() As String
Get
Return Me.relField
End Get
Set(value As String)
Me.relField = value
End Set
End Property
'''<remarks/>
<System.Xml.Serialization.XmlAttributeAttribute()> _
Public Property href() As String
Get
Return Me.hrefField
End Get
Set(value As String)
Me.hrefField = value
End Set
End Property
End Class
然后将xml反序列化为这些类。使用LINQ查找唯一带有name = "descriptor.ovf"
的*元素。根据需要添加异常处理。
Sub Main()
Dim myVApp As VApp
Dim serializer As New XmlSerializer(GetType(VApp))
Using sr As New StreamReader("XMLFile1.xml")
myVApp = CType(serializer.Deserialize(sr), VApp)
End Using
Dim href = myVApp.Files.Single(Function(f) f.name = "descriptor.ovf").Link.href
Console.WriteLine(href)
Console.ReadLine()
End Sub
输出:
*您可以将Single
,Where
或First
与同一谓词一起使用,以分别返回唯一的项目,所有项目或具有该名称的第一项。