为什么我会得到 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>
由于
答案 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