当子元素具有特定文本时如何从XML提取父值

时间:2019-01-29 11:51:07

标签: c# xml vb.net api xml-parsing

我张贴到一个api,该api返回显示我已发布订单状态的xml。目前,要获取警告代码和警告消息,这是我所做的并且可以正常工作

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {

    //here you trigger the LocalBroadcastManager in your activity
    Intent pushNotification = new Intent(AppConfig.PUSH_NOTIFICATION);
    LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);

}

我这样调用上述方法

Private Shared Function GetXMLElementValue(xml As String, element As String) As String
    Try
        Dim xDoc As XDocument = XDocument.Parse(xml)
        Dim node = xDoc.Descendants().Where(Function(n) n.Name = element).FirstOrDefault()
        Dim nodeValue As String = ""
        If node IsNot Nothing Then
            nodeValue = node.Value
        End If
        Return nodeValue
    Catch ex As Exception
        Return Nothing
    End Try
End Function

仅发布了几个订单时,上述方法就可以正常工作,但是现在我发布了300个订单,事实证明很难找到发出警告的顺序。

例如返回的XML

Dim warningCode = GetXMLElementValue(responseReceivedFromApi, "warningCode")
Dim warningMessage = GetXMLElementValue(responseReceivedFromApi, "warningMessage")

我想获取有警告的订单参考(148956)。我不确定如何实现这一目标。任何帮助是极大的赞赏。

2 个答案:

答案 0 :(得分:0)

您可以使用的一个选项是创建一个名为GetXMLElement的函数,该函数将返回整个XElement而不是单个值,然后您可以浏览其Parent属性以查找位置它连接到。例如:

Private Shared Function GetXMLElement(xml As String, element As String) As XElement
    Try
        Dim xDoc As XDocument = XDocument.Parse(xml)
        Dim node = xDoc.Descendants().Where(Function(n) n.Name = element).FirstOrDefault()

        Return node
    Catch ex As Exception
        Return Nothing
    End Try
End Function

按以下方式使用:

Dim warningCode = GetXMLElement(responseReceivedFromApi, "warningCode")
Dim warningMessage = GetXMLElement(responseReceivedFromApi, "warningMessage")

If (Not warningCode Is Nothing) Then
    Debug.Print(warningCode.Parent.Parent.Parent.ToString)
End If

warningCode元素的父级为warning,下一个父级为warnings。您最感兴趣的父级是order元素

然后,将输出:

<order>
  <orderReference>148956</orderReference>
  <status>Updated</status>
  <warnings>
    <warning>
      <warningCode>1116</warningCode>
      <warningMessage><![CDATA["Address is inaccurate"]]></warningMessage>
    </warning>
  </warnings>
</order>

答案 1 :(得分:0)

一次即可获得所需信息,而不是多次通话。遵循以下原则:

Dim orders As XElement = <orders>
<order>
  <orderReference>148933</orderReference>
  <status>Updated</status>
</order>
<order>
  <orderReference>148955</orderReference>
  <status>Updated</status>
</order>
<order>
  <orderReference>148956</orderReference>
  <status>Updated</status>
  <warnings>
    <warning>
      <warningCode>1116</warningCode>
      <warningMessage><![CDATA["Address is inaccurate"]]></warningMessage>
    </warning>
  </warnings>
</order>
<order>
  <orderReference>149025</orderReference>
  <status>Updated</status>
</order>
<order>
  <orderReference>149034</orderReference>
  <status>Updated</status>
</order>
</orders>


 Dim orderWithWarning = orders.Descendants("warnings") _
    .Select(Function(wr) New With { _
            .OrderReference =  wr.Parent.<orderReference>.Value, _
            .WarningCode = wr.<warning>.<warningCode>.Value, _
            .WarningMessage = wr.<warning>.<warningMessage>.Value _
            }).FirstOrDefault()

这将返回一个Anonymous Type