我如何解析此XML

时间:2014-03-23 22:19:04

标签: .net xml vb.net xml-parsing linq-to-xml

我需要使用Visual Basic .NET解析下面的XML。在过去,我通过XSLT找到了一种解决方法,根据我的需要调整XML,但我真的很想知道如何在没有解决方法的情况下完成这项工作。我先粘贴XML,然后告诉您卡住的地点和原因:

<browse result="1" first="1" last="16" total="16">
    <th>
        <td label="dimension" hideforuser="false" type="String">fin.trs.line.dim2</td>
        <td label="Outstanding" hideforuser="false" type="Value">fin.trs.line.openbasevaluesigned</td>
        <td label="Factuurbedrag" hideforuser="false" type="Value">fin.trs.line.basevaluesigned</td>
        <td label="Invoice Number" hideforuser="false" type="String">fin.trs.line.invnumber</td>
        <td label="" hideforuser="false" type="String">fin.trs.head.code</td>
        <td label="Pay date" hideforuser="false" type="Date">fin.trs.line.matchdate</td>
        <td label="Vervaldatum" hideforuser="false" type="Date">fin.trs.line.datedue</td>
        <td label="Datum" hideforuser="false" type="Date">fin.trs.head.date</td>
        <td label="boektype" hideforuser="false" type="String">fin.trs.head.status</td>
        <td label="paystatus" hideforuser="false" type="String">fin.trs.line.availableforpayruns</td>
    </th>
    <tr>
        <td field="fin.trs.line.dim2" hideforuser="false" type="String">01603</td>
        <td field="fin.trs.line.openbasevaluesigned" hideforuser="false" type="Value">-792.00</td>
        <td field="fin.trs.line.basevaluesigned" hideforuser="false" type="Value">-800.00</td>
        <td field="fin.trs.line.invnumber" hideforuser="false" type="String">789</td>
        <td field="fin.trs.head.code" hideforuser="false" type="String">INK</td>
        <td field="fin.trs.line.matchdate" hideforuser="false" type="Date" name="14/03/2012">20120314</td>
        <td field="fin.trs.line.datedue" hideforuser="false" type="Date" name="13/04/2012">20120413</td>
        <td field="fin.trs.head.date" hideforuser="false" type="Date" name="14/03/2012">20120314</td>
        <td field="fin.trs.head.status" hideforuser="false" type="String" name="Definitief">final</td>
        <td field="fin.trs.line.availableforpayruns" hideforuser="false" type="String" name="Ja">true</td>
        <key>
            <office>DACMI3-1</office>
            <code>INK</code>
            <number>201200019</number>
            <line>1</line>
        </key>
    </tr>
<tr>
        <td field="fin.trs.line.dim2" hideforuser="false" type="String">11123</td>
        <td field="fin.trs.line.openbasevaluesigned" hideforuser="false" type="Value">300.00</td>
        <td field="fin.trs.line.basevaluesigned" hideforuser="false" type="Value">300.00</td>
        <td field="fin.trs.line.invnumber" hideforuser="false" type="String">11112</td>
        <td field="fin.trs.head.code" hideforuser="false" type="String">INK</td>
        <td field="fin.trs.line.matchdate" hideforuser="false" type="Date"/>
        <td field="fin.trs.line.datedue" hideforuser="false" type="Date" name="13/04/2012">20120413</td>
        <td field="fin.trs.head.date" hideforuser="false" type="Date" name="14/03/2012">20120314</td>
        <td field="fin.trs.head.status" hideforuser="false" type="String" name="Definitief">final</td>
        <td field="fin.trs.line.availableforpayruns" hideforuser="false" type="String" name="Ja">true</td>
        <key>
            <office>DACMI3-1</office>
            <code>INK</code>
            <number>201200021</number>
            <line>1</line>
        </key>
    </tr>
    </browse>

为了让每个人都能阅读它,我已经截断了XML。实际的XML中还有大约15个<tr>个部分。 XML是我从网络服务获得的响应。

我已经尝试过我可以在网上找到的每一段代码,但是每个人和每个人都陷入困境。这就是为什么我不会告诉你我已经尝试过的东西,请接受我的话,我已经花了两年时间。

我的问题是什么

1 即可。正如您所看到的,XML以<th>部分开头(这对我来说并不重要,只是网络服务告诉我我要求的内容)。所以这部分需要被忽视。但它处于同一水平&#39;作为我需要的<tr>块,那么如何跳过<th>并从<tr>开始?和for each tr一样。

2 即可。我需要<tr>块中的每个值和名称,但名称不是由标签指定,而是由属性指定。如果你看一下<tr>块;而不是

<dim2>01603</dim2>

它被放下

<td field="fin.trs.line.dim2" hideforuser="false" type="String">01603</td>

对于每个<tr>块,我需要fin.trs.line.dim2部分(因此字段名称)和实际值。那我该怎么做呢?

第3 即可。每个<tr>块都有一个名为<key>的子节点,它(就像它告诉的那样)保存每个块的键值。如何检索这些值,并确保我知道它们属于它所在的<tr>块?

我一直在阅读教程和网站,但我似乎无法理解这一部分。

只是为了确保,这适用于Visual Basic NET(2010,如果你需要知道的话)。

P.S。:XML是一个字符串。

1 个答案:

答案 0 :(得分:0)

您可以使用LINQ2XML仅获取tr个元素,然后从th中提取属性元素使用XDocument.DescendantsXAttribute方法。要查找元素,请在tr元素上再次使用 Descendants 方法。解决方案可能如下所示:

dim xmlSource = File.ReadAllText("d:\temp\source.xml")
' read the XML (HTML) code
dim xml = XDocument.Parse(xmlSource)
' find all tr elements
dim trs = xml.Root.Descendants("tr").ToList()
' iterate over each one of them
for Each tr in trs
    ' find all td elements for each tr
    dim tds = tr.Descendants("td")
    ' iterate over each one of them
    for each td as XElement in tds
        ' find the attribute with the name field
        dim attr as XAttribute = td.Attribute("field")
        ' if found
        if not (attr.Value = nothing) then
            ' take the attribute name and the element value (td value)
            Console.WriteLine(String.Format("{0} - {1}", attr.Value, td.Value))
        end if
    next
    ' find element key that belongs to this tr
    dim keys = tr.Descendants("key")
    for each key as XElement in keys
        dim keyNodes = key.Elements()
        for each keyNode as XElement in keyNodes
            Console.WriteLine(String.Format("{0} - {1}", keyNode.Name, keyNode.Value))
        next
    next
next

输出(只是其中的一部分):

...
fin.trs.head.date - 20120314
fin.trs.head.status - final
fin.trs.line.availableforpayruns - true
office - DACMI3-1
code - INK
number - 201200021
line - 1