使用 LINQ 在 XML 和 VB.Net 的后代中搜索特定值

Search certain value in descendants with LINQ to XML with VB.Net

这是我正在处理的 xml 文件的摘要

<?xml version="1.0" encoding="utf-8"?>
<Devoluciones>
  <Remesa>
    <Archivo>PRE20180403140755376539AD95PSPTJ7E6</Archivo>
    <TxInfAndSts>
      <OrgnlInstrId>PRE20180403140755376539AD95PSPTJ7E6</OrgnlInstrId>
      <OrgnlEndToEndId>5099</OrgnlEndToEndId>
      <StsRsnInf>
        <Rsn>
         <Cd>MD01</Cd>
        </Rsn>
      </StsRsnInf>
    </TxInfAndSts>
  </Remesa>
  <Remesa>
    <Archivo>PRE201804031123897319287123098AC78C</Archivo>
    <TxInfAndSts>
      <OrgnlInstrId>PRE201804031123897319287123098AC78C</OrgnlInstrId>
      <OrgnlEndToEndId>2141</OrgnlEndToEndId>
      <StsRsnInf>
        <Rsn>
          <Cd>MD01</Cd>
        </Rsn>
      </StsRsnInf>
    </TxInfAndSts>
    <TxInfAndSts>
      <OrgnlInstrId>PRE201804031123897319287123098AC78C</OrgnlInstrId>
      <OrgnlEndToEndId>2313</OrgnlEndToEndId>
      <StsRsnInf>
        <Rsn>
          <Cd>AC04</Cd>
        </Rsn>
      </StsRsnInf>
    </TxInfAndSts>
  </Remesa>
</Devoluciones>

我正在尝试使用下面的代码在具有某些值的父对象中找到标签 Cd 的值。它有效,但我认为它可以简化。

    Dim archivoSEPA As String = "PRE201804031123897319287123098AC78C"
    Dim RefAdeudo As Integer = "2313"
    Dim xml As XElement = XElement.Load(path)
    Dim OrgnlInstrId, OrgnlEndToEndId, TxInfAndSts As XElement
    Dim dev As String = String.Empty

    If xml.Descendants.Where(Function(el) el.Name.LocalName = "OrgnlInstrId" And el.Value = archivoSEPA).Count <> 0 Then
        OrgnlInstrId = xml.Descendants.Where(Function(el) el.Name.LocalName = "OrgnlInstrId" And CStr(el.Value) = archivoSEPA).First
        If OrgnlInstrId.Parent.Descendants.Where(Function(el) el.Name.LocalName = "OrgnlEndToEndId" And el.Value = RefAdeudo.ToString).Count <> 0 Then
            OrgnlEndToEndId = OrgnlInstrId.Parent.Descendants.Where(Function(el) el.Name.LocalName = "OrgnlEndToEndId" And el.Value = RefAdeudo.ToString).First
            TxInfAndSts = OrgnlEndToEndId.Parent
            dev = TxInfAndSts.Descendants.Where(Function(el) el.Name.LocalName = "StsRsnInf").First _
                .Descendants.Where(Function(el) el.Name.LocalName = "Rsn").First _
                .Descendants.Where(Function(el) el.Name.LocalName = "Cd").Value
        End If
    End If

非常感谢(对不起我的英语!)

是的,您的查询可以简化...这里是一个单行:

Dim q = xdoc...<TxInfAndSts>.Where(Function(c) c.<OrgnlInstrId>.Count > 0 And c.<OrgnlInstrId>.First.Value = archivoSEPA).Where(Function(c) c.<OrgnlEndToEndId>.Count > 0 And c.<OrgnlEndToEndId>.First.Value = RefAdeudo)

以下是供审查的样本存根:

Dim xdoc As XDocument = <?xml version="1.0" encoding="utf-8"?>
                                    <Devoluciones>
                                        <Remesa>
                                            <Archivo>PRE20180403140755376539AD95PSPTJ7E6</Archivo>
                                            <TxInfAndSts>
                                                <OrgnlInstrId>PRE20180403140755376539AD95PSPTJ7E6</OrgnlInstrId>
                                                <OrgnlEndToEndId>5099</OrgnlEndToEndId>
                                                <StsRsnInf>
                                                    <Rsn>
                                                        <Cd>MD01</Cd>
                                                    </Rsn>
                                                </StsRsnInf>
                                            </TxInfAndSts>
                                        </Remesa>
                                        <Remesa>
                                            <Archivo>PRE201804031123897319287123098AC78C</Archivo>
                                            <TxInfAndSts>
                                                <OrgnlInstrId>PRE201804031123897319287123098AC78C</OrgnlInstrId>
                                                <OrgnlEndToEndId>2141</OrgnlEndToEndId>
                                                <StsRsnInf>
                                                    <Rsn>
                                                        <Cd>MD01</Cd>
                                                    </Rsn>
                                                </StsRsnInf>
                                            </TxInfAndSts>
                                            <TxInfAndSts>
                                                <OrgnlInstrId>PRE201804031123897319287123098AC78C</OrgnlInstrId>
                                                <OrgnlEndToEndId>2313</OrgnlEndToEndId>
                                                <StsRsnInf>
                                                    <Rsn>
                                                        <Cd>AC04</Cd>
                                                    </Rsn>
                                                </StsRsnInf>
                                            </TxInfAndSts>
                                        </Remesa>
                                    </Devoluciones>
            Dim archivoSEPA$ = "PRE201804031123897319287123098AC78C", RefAdeudo% = 2313
            Dim q = xdoc...<TxInfAndSts>.Where(Function(c) c.<OrgnlInstrId>.Count > 0 And c.<OrgnlInstrId>.First.Value = archivoSEPA).Where(Function(c) c.<OrgnlEndToEndId>.Count > 0 And c.<OrgnlEndToEndId>.First.Value = RefAdeudo)
            If q.Count > 0 Then
                MsgBox(IIf(q.First...<Cd>.Count > 0, q.First...<Cd>.First.Value, "No such element found!"))
            End If

希望这对您有所帮助...