简体   繁体   中英

How to properly parse this xml response

We are using a currency service for currency exchange. There xml web response is not in the greatest format. It looks like such

<RESPONSE>
   <EXPR>USD</EXPR> 
   <EXCH>CAD</EXCH> 
   <AMOUNT>1</AMOUNT> 
   <NPRICES>1</NPRICES> 
   <CONVERSION>
      <DATE>Thu, 07 Apr 2011 21:00:00 GMT</DATE> 
      <ASK>1.0418</ASK> 
      <BID>1.0415</BID> 
   </CONVERSION>
   <EXPR>USD</EXPR> 
   <EXCH>AUD</EXCH> 
   <AMOUNT>1</AMOUNT> 
   <NPRICES>1</NPRICES> 
   <CONVERSION>
      <DATE>Thu, 07 Apr 2011 21:00:00 GMT</DATE> 
      <ASK>1.0461</ASK> 
      <BID>1.0459</BID> 
   </CONVERSION>
</RESPONSE>

So I tried to write the following SQL Statement

SELECT 
    T.c.value('../EXPR[1]', 'VARCHAR(3)')
,   T.c.value('../EXCH[1]', 'VARCHAR(3)')
,   T.c.value('ASK[1]', 'MONEY')
FROM @xml.nodes('/RESPONSE/CONVERSION') T(c)

But since both Headers (EXPR and EXCH) are on the same level, is there anyway I can pick the Expr that is above the conversion. I understand how I would accomplish that.

If your nodes are always in the same order, you can try the following before beginning to parse is:

1) Remove the , tags: eg xmlString = xmlString.Replace("", string.empty) ...

2) Split your string: entries[] = xmlString.Split(""); or use Regex.Split

3) Add missing tags to all entries: , ,

4) Parse the entries

If you do something like this:

using System.Xml;

public class TestClass
{
    void ParseXML(string xml)
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);

        XmlNodeList list = doc.GetElementsByTagName("EXPR");
    }
}

In that example list[0] should contain the first instance of the EXPR tag.

The idea here is to select all the EXPR, EXCH, and ASK nodes in document-order, and join them on the assigned row-number:

select
    exprn.val
,   exchn.val
,   askn.val
FROM 
(select expr.e.value('.', 'VARCHAR(3)') as val, row_number() over(order by expr.e) n from @xml.nodes('/RESPONSE/EXPR') expr(e)) exprn

join (select exch.e.value('.', 'VARCHAR(3)') as val, row_number() over(order by exch.e) n from @xml.nodes('/RESPONSE/EXCH') exch(e)) exchn on exchn.n = exprn.n

join (select ask.a.value('.', 'MONEY') as val, row_number() over(order by ask.a) n from @xml.nodes('/RESPONSE/CONVERSION/ASK') ask(a)) askn on askn.n = exprn.n

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM