使用VB.Net的LINQ to XML在子节点中查找特定值
嘿,我刚好熟悉VB.NET里的LINQ to XML操作,针对你给出的XML结构,我给你整理几个实用的查找场景和代码示例,应该能解决你的问题。
首先先明确你的XML层级:<Devoluciones>是根节点,下面包含多个<Remesa>,每个<Remesa>里有<Archivo>和<TxInfAndSts>,<TxInfAndSts>又嵌套了<OrgnlInstrId>、<OrgnlEndToEndId>以及状态相关的<StsRsnInf>节点。
1. 先加载XML文档
不管你的XML是来自文件还是字符串,都可以用XDocument来加载:
' 从本地文件加载XML Dim xmlDoc As XDocument = XDocument.Load("你的XML文件路径.xml") ' 如果是从字符串获取XML,用Parse方法 ' Dim xmlContent As String = "你的XML完整字符串内容" ' Dim xmlDoc As XDocument = XDocument.Parse(xmlContent)
2. 常见查找场景示例
场景1:查找特定<OrgnlEndToEndId>值对应的交易节点
比如要找所有<OrgnlEndToEndId>为"5099"的<TxInfAndSts>,还顺带获取所属的<Archivo>和状态码:
' 筛选OrgnlEndToEndId等于"5099"的TxInfAndSts节点 Dim targetTransactions = From txNode In xmlDoc.Descendants("TxInfAndSts") Where txNode.Element("OrgnlEndToEndId").Value = "5099" Select txNode ' 遍历结果,提取需要的信息 For Each tx In targetTransactions ' 获取父节点Remesa下的Archivo值 Dim archivoName = tx.Parent.Element("Archivo").Value Console.WriteLine($"找到匹配交易,所属Archivo:{archivoName}") ' 获取状态码Cd的值(注意节点可能不存在,用FirstOrDefault避免报错) Dim statusCode = tx.Descendants("Cd").FirstOrDefault()?.Value If statusCode IsNot Nothing Then Console.WriteLine($"交易状态码:{statusCode}") End If Next
场景2:查找包含特定状态码<Cd>的<Remesa>节点
比如要找所有<Cd>值为"MD01"的<Remesa>:
' 筛选包含Cd为"MD01"的Remesa节点 Dim targetRemesas = From remesaNode In xmlDoc.Descendants("Remesa") Where remesaNode.Descendants("Cd").Any(Function(cd) cd.Value = "MD01") Select remesaNode For Each remesa In targetRemesas Console.WriteLine($"匹配的Remesa的Archivo:{remesa.Element("Archivo").Value}") Dim originalInstrId = remesa.Descendants("OrgnlInstrId").FirstOrDefault()?.Value Console.WriteLine($"原始指令ID:{If(originalInstrId, "未找到该节点")}") Next
场景3:根据<Archivo>值,获取对应的<OrgnlEndToEndId>
比如已知Archivo的值,要快速找到对应的交易ID:
Dim targetArchivo As String = "PRE20180403140755376539AD95PSPTJ7E6" ' 查找匹配的Archivo对应的OrgnlEndToEndId Dim endToEndId = (From remesa In xmlDoc.Descendants("Remesa") Where remesa.Element("Archivo").Value = targetArchivo Select remesa.Descendants("OrgnlEndToEndId").FirstOrDefault()?.Value).FirstOrDefault() If endToEndId IsNot Nothing Then Console.WriteLine($"Archivo {targetArchivo}对应的EndToEndId:{endToEndId}") Else Console.WriteLine($"未找到Archivo为{targetArchivo}的节点") End If
3. 一些需要注意的点
- 节点名称大小写敏感:LINQ to XML对节点名称的大小写是严格区分的,确保你代码里写的节点名和XML里的完全一致(比如不要把
TxInfAndSts写成txinfandsts)。 - 避免空引用异常:如果某个节点可能不存在(比如有些
<TxInfAndSts>可能没有<StsRsnInf>),一定要用FirstOrDefault()代替First(),并且用?.空传播操作符来访问Value属性。 - 处理命名空间:如果你的XML文档带有命名空间,需要先声明命名空间再使用,示例如下:
' 假设XML的命名空间是http://example.com/devoluciones Dim ns As XNamespace = "http://example.com/devoluciones" ' 引用节点时要加上命名空间 Dim targetNodes = xmlDoc.Descendants(ns + "TxInfAndSts")
内容的提问来源于stack exchange,提问作者Pyrus
相关产品推荐
相关产品推荐

