Visual Basic中的XPath

少年赞坎

我在Visual Basic中遇到“ SelectSingleNode”功能的问题。

我有以下XML文件:

<sistema versao="1.02" xmlns="http://www.portalfiscal.inf.br/nfe">
<det>
<prod>
    <cProd>000085</cProd>
    <xProd>MARTELO</xProd>
    <NCM>73170090</NCM>
    <uCom>UN</uCom>
    <vUnCom>7.0000</vUnCom>
</prod>
<imposto>
    <ICMS>
        <orig>0</orig>
        <CST>500</CST>
    </ICMS>
</imposto>
</det>
</sistema>

我需要节点“ cProd”内的值。在这种情况下,为“ 000085”。

我尝试了以下代码:

    Public Sub importacao()
    Dim arquivos = CheckedListBox1.CheckedItems
    Dim total = arquivos.Count

    Dim nome_produto As String

    For i As Integer = 0 To total - 1
        Dim xml As New XmlDocument

        xml.Load(arquivos.Item(i))

        nome_produto = xml.ChildNodes(0).ChildNodes(0).ChildNodes(0).SelectSingleNode("cProd").InnerText

    Next

End Sub

在“ arquivos”中是带有XML文件路径的CheckBoxList。

返回错误“对象引用未设置为对象的实例”。因为“ SelectSingleNode(” cProd“)”返回空值。

我认为我错误地放置了XPath。有人可以帮我吗?

谢谢,对不起我的英语。

编辑:

它起作用了,我使用一个函数删除了命名空间(源:http : //rprateek.blogspot.com.br/2011/01/how-to-remove-xmlns-namespace-from-xml.html)。然后,我可以使用以下代码:xml.ChildNodes(0).SelectSingleNode("//cProd").InnerText

还有一件事。如果文件中不存在标签“ cProd”(或另一个标签),最可能的处理错误的方法是什么?例如,在某些文件中,将没有标签“ NCM”。也许我可以使用“ GetElementsByTagName()”来验证标签是否存在?

谢谢你们。

乔希·帕特(Josh Part)

如评论中所述,您无需希望遍历节点即可到达所需节点;您可以将整个XPath设置为查找所需的节点。

尽管如此,您的XML还是有一个小问题:它有一个没有前缀的名称空间:

<sistema versao="1.02" xmlns="http://www.portalfiscal.inf.br/nfe">

由于所有节点都有默认的名称空间前缀“看不到”,这使XPath查询有点麻烦,但是它仍然存在。

您有三种选择:

1.-从XML删除名称空间...

<sistema versao="1.02">
<det>
<prod>
    <cProd>000085</cProd>
    <xProd>MARTELO</xProd>
    <NCM>73170090</NCM>
    <uCom>UN</uCom>
    <vUnCom>7.0000</vUnCom>
</prod>
<imposto>
    <ICMS>
        <orig>0</orig>
        <CST>500</CST>
    </ICMS>
</imposto>
</det>
</sistema>

...然后使用

xml.ChildNodes(0).SelectSingleNode("//cProd").InnerText

或者

xml.ChildNodes(0).SelectSingleNode("/sistema/det/prod/cProd").InnerText

2.-指定前缀(ns例如,您可以根据需要命名)...

<ns:sistema versao="1.02" xmlns:ns="http://www.portalfiscal.inf.br/nfe">
<ns:det>
<ns:prod>
    <ns:cProd>000085</ns:cProd>
    <ns:xProd>MARTELO</ns:xProd>
    <ns:NCM>73170090</ns:NCM>
    <ns:uCom>UN</ns:uCom>
    <ns:vUnCom>7.0000</ns:vUnCom>
</ns:prod>
<ns:imposto>
    <ns:ICMS>
        <ns:orig>0</ns:orig>
        <ns:CST>500</ns:CST>
    </ns:ICMS>
</ns:imposto>
</ns:det>
</ns:sistema>

...使用XmlNameSpaceManager...

Dim manager as New XmlNameSpaceManager(xml.NameTable)

...然后使用

xml.ChildNodes(0).SelectSingleNode("//ns:cProd", manager).InnerText

或者

xml.ChildNodes(0).SelectSingleNode("/ns:sistema/ns:det/ns:prod/ns:cProd", manager).InnerText

3.-保留XML不变,并使用其中一个

xml.ChildNodes(0).SelectSingleNode("//*[name()='cProd']").InnerText

还是这个小怪癖

xml.ChildNodes(0).SelectSingleNode("/*[name()='sistema']/*[name()='det']/*[name()='prod']/*[name()='cProd']").InnerText

/* 让您忽略名称空间。

这个问题这个问题可能会帮助您更好地理解该问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章