XPath适用于在线测试程序,在.Net中失败

时间:2018-06-14 17:25:36

标签: vb.net xpath

我有一个租用基本表格数据的大型XML文档......

<Properties>
  <Property>
    <Tenants>
      <Tenant>
        <Name>Foo</Name>
        <Suite>100</Suite>
        <Rent> ... </Rent>
     </Tenant>
     ...
   </Tenants>

我正在尝试为选定的租户/单位提取租金,以便我可以进行基本的数学和报告。我将文件加载到online XPath tester中,经过几次尝试后,该查询才能生效:

//Properties/Property/Tenants/Tenant[Name="Foo" and Suite="100"]/Rent

这返回了该单位的租金。优良!

现在我正在尝试使用System.Xml将其转换为.Net代码。我这样做了:

        Dim SS As String = "//Properties/Property/Tenants/Tenant[Name=""" & NewT.Name & """ and Suite=""" & NewU.Name & """]/Rent"
        Dim NewX As XmlNode = XMLDoc.DocumentElement.SelectSingleNode(SS)

XMLDoc包含完整的文档(在InnerXML上调试),NewT.Name是“Foo”,NewU.Name是“100”,结果字符串显示在Watch窗口中是:

"//Properties/Property/Tenants/Tenant[Name=""Foo"" and Suite=""100""]/Rent"

无法找到该元素。没有错误或异常,我什么也得不回。

我查看过various MS份文件,但我还没有发现任何有用的内容。 System.Xml是否处理“和”查询?或者他们想要一些额外的语法?

更新:进一步测试:XMLDoc.DocumentElement.ChildNodes(2)是属性列表。任何尝试在此节点或任何其他节点上执行任何.Select都不会返回任何内容。这可能是字符集还是某种模式?

2 个答案:

答案 0 :(得分:0)

当我稍微扩大搜索条件时,我能够在另一个帖子中找到答案。当我这样做时,我发现我需要将搜索字符串更改为:

//a:Properties/a:Property/a:Tenants/a:Tenant[Name="Foo" and Suite="100"]/a:Rent

然后将命名空间加载到与所有查询一起使用的管理器中。似乎在标题中添加定义URL对我使用的各种解析器没有区别(也不应该因为在这种情况下只有一个命名空间),但.Net解析器需要它。

我怀疑语法更简单,但工作是一个功能。

答案 1 :(得分:-1)

或者使用我喜欢的XElement和LINQ。

    Dim xe As XElement
    'to load
    '  xe = XElement.Load("URI / Path here")

    'to test

    xe = <Properties>
             <Property>
                 <Tenants>
                     <Tenant>
                         <Name>Foo</Name>
                         <Suite>100</Suite>
                         <Rent>$1000</Rent>
                     </Tenant>
                     <Tenant>
                         <Name>Bar</Name>
                         <Suite>100</Suite>
                         <Rent>$300</Rent>
                     </Tenant>
                 </Tenants>
             </Property>
         </Properties>

    Dim sel As IEnumerable(Of XElement)
    Dim ste As String = "100"
    Dim nm As String = "Foo"

    'select matching suite and name
    sel = From el In xe...<Tenants>.<Tenant>
          Where el.<Suite>.Value = ste AndAlso el.<Name>.Value = nm
          Select el

    'OR select matching suite and name

    sel = From el In xe...<Tenant>
          Where el.<Suite>.Value = ste AndAlso el.<Name>.Value = nm
          Select el

    For Each v As XElement In sel
        Debug.WriteLine("Name: {0}, suite: {1}, rent: {2}", v.<Name>.Value, v.<Suite>.Value, v.<Rent>.Value)
    Next

编辑:评论如何与downvote一起使用,以便我可以修复。