以下xml
<Student>
<Name>Marc</Name>
<Age>20</Age>
</Student>
<Student>
<Name>Peter</Name>
<Age>30</Age>
</Student>
我试图运行代码来完成所有对象Student。
到目前为止我所做的是(考虑到xmldoc是我的xmlDocuemtn变量)
Dim AllStudentNodes = xmldoc.Selectnodes("/Student")
For each item in AllStudentNodes
Name = xmlDoc.SelectSingleNode("/Student/Name").InnerText
Next
如果有两个名为Student的节点,那么它只会取第一个学生名两次,如果有三个名为Student的节点则会有三个。
似乎它会多次停留在第一个节点上,并且学生节点就会存在,即使它们不同,它也不会遍历所有节点。
有什么建议吗?
代码
xmlDoc.Load(Request.InputStream)
xmlCXMLNode = xmlDoc.SelectSingleNode("cXML")
Dim ItemOutNodes = xmlCXMLNode.SelectNodes("/cXML/Request/OrderRequest/ItemOut")
For Each Item In ItemOutNodes
Try
Node_IO_LineNumber = Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut").Attributes("lineNumber")
IO_LineNumber = GetInnerText(Node_IO_LineNumber)
Node_IO_Quantity = Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut").Attributes("quantity")
IO_Quantity = GetInnerText(Node_IO_Quantity)
Node_IO_RequestedDeliverYDate = Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut").Attributes("requestedDeliveryDate")
IO_RequestedDeliveryDate = GetInnerText(Node_IO_RequestedDeliverYDate).Split("+")
IO_RequestedDeliveryDateInsert = IO_RequestedDeliveryDate(0).Replace("T", " ")
Node_IO_IID_SupplierPartID = Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut/ItemID/SupplierPartID")
IO_IID_SupplierPartID = GetInnerText(Node_IO_IID_SupplierPartID)
IO_IID_SupplierPartID = IO_IID_SupplierPartID.Replace("#", "Ñ")
Node_IO_IID_BuyerPartID = Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut/ItemID/BuyerPartID")
IO_IID_BuyerPartID = GetInnerText(Node_IO_IID_BuyerPartID)
Node_IO_ID_UP_Money = Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut/ItemDetail/UnitPrice/Money")
IO_ID_UP_Money = GetInnerText(Node_IO_ID_UP_Money)
Node_IO_ID_Descrption = Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut/ItemDetail/Description")
IO_ID_Description = GetInnerText(Node_IO_ID_Descrption)
Catch ex As Exception
Response.Write("Error ItemOut")
ErrorFound = True
ErrorString = ErrorString + "-Error ItemOut"
End Try
Next
答案 0 :(得分:1)
这是因为您实际上请求在整个文档中匹配XPath的第一个节点
您需要在当前迭代的Name
中找到item
元素。
首先需要提及的是您的XML无效 XML必须具有单个根元素。
我们假设您有以下文件:
<root>
<Student>
<Name>Marc</Name>
<Age>20</Age>
</Student>
<Student>
<Name>Peter</Name>
<Age>30</Age>
</Student>
</root>
然后,你可以这样做:
Dim AllStudentNodes = xmldoc.SelectNodes("root/Student")
For each item in AllStudentNodes
Name = item.SelectSingleNode("Name").InnerText
Next
请注意,它是item.SelectSingleNode
,而不是xmlDoc.SelectSingleNode
即,“在我的item
中找到单个名称”,而不是“在我的整个文档中找到单个(第一个)名称”。
<强>更新强>
在您的代码中,您使用以下XPath:
Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut").Attributes("lineNumber")
Item.SelectSingleNode("/cXML/Request/OrderRequest/ItemOut/ItemDetail/UnitPrice/Money")
这是绝对的XPath,实际上意味着“从根找到匹配cXML / Request的第一个元素......”。因此,开头的斜线也可以从根文档中搜索
你的XPath应该是相对的。由于您的Item
已经ItemOut
,因此可以简单地说:
Item.Attributes("lineNumber")
Item.SelectSingleNode("ItemDetail/UnitPrice/Money")
它就像文件夹结构或URL一样简单
您打开example.com/ItemOut
网址,如果您遇到ItemDetail.html
之类的相对链接,则会打开example.com/ItemOut/ItemDetail.html
。如果您在/ItemDetail.html
开头放置一个斜杠,它将打开绝对example.com/ItemDetail.html
。
答案 1 :(得分:0)
Yeldar的答案很好,但我会用XElement
代替XmlDocument向您展示另一种方式。
我更喜欢XElement
,因为它具有华丽的VB .NET语法和完整的Linq支持:
Dim xml as XElement = <Students>
<Student>
<Name>Marc</Name>
<Age>20</Age>
</Student>
<Student>
<Name>Peter</Name>
<Age>30</Age>
</Student>
</Students>
'OR if you have/want to use XmlDocument:'
Dim xmlDoc = New XmlDocument()
xmlDoc.LoadXml("YourXmlAsString")
xml = XElement.Load(xmlDoc.CreateNavigator().ReadSubtree)
Dim studentNames As IEnumerable(Of XElement) = xml.<Student>.<Name>
'Also possible:'
studentNames = xml...<Name>
For Each name In studentNames
Console.WriteLine(name.Value)
Next