MS.Internal.Xml.Xpath.XpathSelectionIterator而不是文本节点的值

时间:2016-09-05 22:11:19

标签: xml vb.net xpath evaluate

为什么我会得到 MS.Internal.Xml.Xpath.XpathSelectionIterator 而不是文本节点的值 在这行代码上

Dim encoding As New System.Text.UTF8Encoding(True)
Dim reader As New System.IO.StreamReader(temparray(0).ToString, encoding)
Dim x As XPathDocument = New XPathDocument(reader)
reader.Close() '?
Dim nav As XPathNavigator
nav = x.CreateNavigator()
nav.Evaluate("//*[name()='mcd-Lol'][*[name()='mcd-Number' and text()='1'] and *[name()='mcd-Tamanho' and text()='2']]//*[name()='mcd-Den']/text()")

而在这个在线测试仪 http://codebeautify.org/Xpath-Tester 它有效吗?

Xml只有文本节点,并且都有名称空间。

<?xml version="1.0" encoding="UTF-8" ?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"   xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
     xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:mcd="urn:acss:ccf:facturacaoelectronica:schema:xsd:Normalizados">
<ext:UBLExtensions>
<ext:UBLExtension>
<ext:ExtensionVersionID>NormalizadosExtension:1.0</ext:ExtensionVersionID>
<ext:ExtensionContent>
<mcd:NormalizadosExtension>
<mcd:TotalCare>134.49</mcd:TotalCare>
-<mcd:Lol>
<mcd:Number>1</mcd:Number>
<mcd:Tamanho>2</mcd:Tamanho>
<mcd:Area>Z</mcd:Area>
<mcd:TotalCare>124.94</mcd:TotalCare>
-<mcd:Qual>
<mcd:Area>Z</mcd:Area>
<mcd:NumeroQual>1040192667866500</mcd:NumeroQual>
<mcd:Data>2011-11-29</mcd:Data>
-<mcd:Care>
<mcd:NumeroLinha>1</mcd:NumeroLinha>
<mcd:Den>facial</mcd:Den>
<mcd:Quant>1</mcd:Quant>
</mcd:Care>
...
</mcd:Qual>
...
</mcd:Lol>

由于

2 个答案:

答案 0 :(得分:0)

据推测,Xpath-Tester为你提供了一个字符串,你可以看到&#34;完美地工作&#34;因为这就是你想要的。但是Xpath-Tester并没有使用XPathNavigator.Evaluate()。根据文档,后者返回&#34;表达式的结果(布尔值,数字,字符串或节点集)。&#34;传入的XPath表达式选择一组文本节点(因为它是long)。因此,根据文档,Evaluate()返回一个节点集;文档说&#34;它分别映射到Boolean,Double,String或XPathNodeIterator对象。&#34;因此,您将获得XPathNodeIterator结果,以迭代文本节点集。

如果你只想要(第一个)文本节点的字符串值,你可以在你的XPath表达式周围包裹blah/blah/blah/text()

string()

我不会问你为什么要使用nav.Evaluate("string(//*[name()='mcd-Lol'][*[name()='mcd-Number' and text()='1'] and *[name()='mcd-Tamanho' and text()='2']]//*[name()='mcd-Den']/text())") ,使用连字符而不是冒号,而不是使用name()='mcd-Lol'和可能的命名空间映射。你没有问过这个问题,所以我想你已经有了这个部分。

答案 1 :(得分:0)

您可以使用xml linq

Imports System.IO
Imports System.Xml
Imports System.Xml.Linq
Module Module1
    Const FILENAME As String = "c:\temp\test.xml"
    Sub Main()
        Dim xml As String = File.ReadAllText(FILENAME)
        Dim doc As XDocument = XDocument.Parse(xml)
        Dim invoice As XElement = CType(doc.FirstNode, XElement)
        Dim mcdNs = invoice.GetNamespaceOfPrefix("mcd")

        Dim results As XElement  = invoice.Descendants(mcdNs + "Lol") _
                      .Where(Function(x) (CType(x.Element(mcdNs + "Number"), Integer) = 1) And _
                                         (CType(x.Element(mcdNs + "Tamanho"), Integer) = 2)) _
                      .FirstOrDefault()

    End Sub

End Module