读取具有相同名称

时间:2016-06-17 07:50:21

标签: xml vb.net nodes

以下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

2 个答案:

答案 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中找到单个名称”,而不是“在我的整个文档中找到单个(第一个)名称”。

以下是 working .NET Fiddle Demo

<强>更新

在您的代码中,您使用以下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