2

我在文件中有以下 xml(简化):

<?xml version="1.0" encoding="ISO-8859-1"?>
<XCer xmlns="http://x.y.z" xmlns:xsi="http://www.x.y.z" xsi:schemaLocation="http://www.x.y.z" track_id="559" mp_id="398" sub_id="569">
<capability xsi:type="XCracT">
<type>rec</type>
<sub_type>pc</sub_type>
<action>reco</action>
</capability>

<final_result OD="DGS=1.6" creator="Creator1" version="1.11" xsi:type="XCarT">
<code>300000000</code>
<code_cnf>0.7454</code_cnf>
<code_attr>seq</code_attr>
<status_attr>fdos</status_attr>
<text>this text</text>
<standardized_text>other text</standardized_text>
<region>
  <type>add</type>
  <symbology>machine</symbology>
</region>
</final_result>

<final_result OD="DGS=1.7" creator="Creator2" version="1.11" xsi:type="XCarT">
<code>3040280100015</code>
<code_cnf>0.7454</code_cnf>
<code_attr>seq</code_attr>
<status_attr>fdos</status_attr>
<text>this text</text>
<standardized_text>other text</standardized_text>
<region>
  <type>add</type>
  <symbology>machine</symbology>
</region>
    <polygon>
    <dot x="849" y="1600"/>
    <dot x="823" y="1600"/>
    <dot x="819" y="1166"/>
    <dot x="845" y="1166"/>
    </polygon>
</final_result>
</XCer>

在一个非常基本的级别上,我想创建 3 个变量:创建者、代码、mp_id 并用最终结果 OD="DGS=1.6" 部分的详细信息填充它们,即“Creator1”、“300000000”、“398”(来自第一个 XCer 元素)和“此文本”,但尽管在过去几天尝试了几次速成课程,但我的 xml 技能非常缺乏。

我已经尝试过基本的

Using reader As XmlReader = XmlReader.Create("C:\filename.xml")  
while reader.Read()  
if reader.IsStartElement() Then  
If reader.Name = "code" Then  
code = reader.ReadElementContentAsString()  

这让我得到了代码,但我无法获得行内的任何元素
final_result OD="DGS=1.6" creator="Creator1" version="1.11" xsi:type="XCarT">

而且我不能在不覆盖之前的代码的情况下将我想要的代码元素限制在该子树中。

4

2 回答 2

2

下面是一个使用 XPath 的简单示例:

Dim doc As New XmlDocument()
doc.Load("Test.xml")
Dim namespaceManager As New XmlNamespaceManager(doc.NameTable)
namespaceManager.AddNamespace("x", "http://x.y.z")
Dim mp_id As String = doc.SelectSingleNode("/x:XCer[1]/@mp_id", namespaceManager).InnerText
Dim creator As String = doc.SelectSingleNode("/x:XCer[1]/x:final_result[@OD='DGS=1.6']/@creator", namespaceManager).InnerText
Dim code As String = doc.SelectSingleNode("/x:XCer[1]/x:final_result[@OD='DGS=1.6']/x:code", namespaceManager).InnerText

请注意,我需要指定命名空间,因为所有元素都有一个默认命名空间http://x.y.z. 出于我的目的,我给命名空间添加了前缀x,但您可以随意命名。

XPath 是一种用于查询 XML 文档的标准语言。有些人更喜欢 Microsoft 的专有 LINQ 技术,但由于 XPath 是其他语言、工具和技术所使用的,因此值得花时间学习它。和方法允许您使用 XPath 查找匹配节点 SelectSingleNodeSelectNodes

第一个选择 的 XPathmp_id如下所示:

/x:XCer[1]/@mp_id

  • /- 从文档的根目录开始
  • x:XCerXCer- 找到一个名为(在x命名空间中)的元素
  • [1]- 仅选择第一个XCer元素
  • /- 寻找第一个XCer元素的后代节点
  • @mp_id- 选择mp_id属性(这是第一个XCer元素的后代节点)

下一个选择creator属性的 XPath 如下所示:

/x:XCer[1]/x:final_result[@OD='DGS=1.6']/@creator

这个开始与上一个相同,但不是选择XCer元素的属性,而是选择final_result子元素。是[@OD='DGS=1.6']条件从句。您可以将其阅读为“选择final_resultOD属性等于的元素DGS=1.6”。

于 2013-05-10T13:07:13.337 回答
0

如果您不知道底层 XML 结构并尝试根据某个标记名称查找节点。注意:xml 可能针对搜索的标签定义了命名空间。在下面的示例中,我们正在搜索 XML 标记CashInAccountNumber,但在实际的 xml 中,它具有命名空间声明,如"bctr:CashInAccountNumber"。以下是xml结构:

<xfa:data xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/"><bctr:BSAForm xmlns:bctr="http://www.fincen.gov/bsa/bctr/2011-06-01" xmlns:cc="http://www.fincen.gov/bsa/common-components/2009-01-01" xmlns:est="http://www.fincen.gov/bsa/efile-submission-types/2009-01-01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><bctr:PersonInformation><bctr:CashInAccountNumber><bctr:CashInAccountNumber /></bctr:CashInAccountNumber><bctr:CashOutAccountNumber><bctr:CashOutAccountNumber /></bctr:CashOutAccountNumber></bctr:PersonInformation><xfdf:field xmlns:xfdf="http://ns.adobe.com/xfdf/" xmlns:xfdfi="http://ns.adobe.com/xfdf-transition/" xfdfi:original="FSAPPLICATIONDATA_">n6835LaAwLhBAAA</xfdf:field><xfdf:field xmlns:xfdf="http://ns.adobe.com/xfdf/" xmlns:xfdfi="http://ns.adobe.com/xfdf-transition/" xfdfi:original="FSTARGETURL_">https://sdtmut1.fincen.treas.gov/AltSubmitServlet</xfdf:field></bctr:BSAForm><FSTEMPLATE_ /><FSFORMQUERY_>BCTR.pdf</FSFORMQUERY_><FSTRANSFORMATIONID_>PDFForm</FSTRANSFORMATIONID_><FSTARGETURL_>https://sdtmut1.fincen.treas.gov/AltSubmitServlet</FSTARGETURL_><FSAWR_>https://sdtmut1.fincen.treas.gov/</FSAWR_><FSWR_>https://sdtmut1.fincen.treas.gov/FormServer</FSWR_><FSCRURI_>/opt/weblogic/user_projects/domains/BSADomain/applications/FinCEN1/forms</FSCRURI_><FSBASEURL_>https://sdtmut1.fincen.treas.gov/</FSBASEURL_></xfa:data>

在这种情况下,如果仍未找到,请尝试使用 decedents("CashInAccountNumber") 方法获取价值,然后使用以下代码片段进行搜索:

        Try
        Dim fs As New FileStream("Your XML File Path", FileMode.Open, FileAccess.Read)

        Dim objDocument As New XPathDocument(fs)
        Dim objNavigator As XPathNavigator = objDocument.CreateNavigator()
        Dim objNodeIterator As XPathNodeIterator = objNavigator.[Select]("//namespace::*[not(. = ../../namespace::*)]")
        While objNodeIterator.MoveNext()
            Dim sKey As String = objNodeIterator.Current.LocalName
            If Not dictNameSpace.ContainsKey(sKey) Then
                dictNameSpace.Add(objNodeIterator.Current.LocalName, objNodeIterator.Current.Value)
            End If
        End While

        fs = New FileStream("Your XML File Path", FileMode.Open, FileAccess.Read)
        Dim xmlr As XDocument = XDocument.Load(fs)

        For Each kvp As KeyValuePair(Of String, String) In dictNameSpace
            Dim ns As XNamespace = kvp.Value
            For Each xEle As XElement In xmlr.Descendants(ns + "CashInAccountNumber")
                Console.WriteLine("Found Tag:" + xEle.Name.LocalName)
            Next xEle
        Next

    Catch ex As Exception
        Console.WriteLine(ex.Message)
    End Try
于 2016-06-14T05:46:10.797 回答