簡體   English   中英

C# 使用 XmlReader 和 XmlWriter 解析 XML

[英]C# Parsing XML with XmlReader and XmlWriter

我正在解析這個 XML:

<?xml version="1.0" encoding="ISO-8859-2"?>
<tabela_kursow typ="A" uid="20a219">
   <numer_tabeli>219/A/NBP/2020</numer_tabeli>
   <data_publikacji>2020-11-09</data_publikacji> 
       <pozycja>
          <nazwa_waluty>bat (Tajlandia)</nazwa_waluty>
          <przelicznik>1</przelicznik>
          <kod_waluty>THB</kod_waluty>
          <kurs_sredni>0,1236</kurs_sredni>
       </pozycja>
       <pozycja>
         <nazwa_waluty>dolar amerykanski</nazwa_waluty>
         <przelicznik>1</przelicznik>
         <kod_waluty>USD</kod_waluty>
         <kurs_sredni>3,7787</kurs_sredni>
       </pozycja>
</tabela_kursow>

我正在使用 XmlReader 從 URL 讀取它並使用 XmlWriter 寫入我的 XML 文件。 但我也有允許的貨幣列表,所以我不想將 URL XML 中的所有貨幣寫入我的 XML 文件。 但是,當我開始編寫部分時,如何有效地測試貨幣是否在我的列表中,但只有當我到達 <kod_waluty> 標簽時,我才能測試我是否想要這種貨幣。 我之前的幾行可以在某處寫入緩沖區,然后再決定是否需要它們嗎?

這是我當前的代碼,它在沒有任何條件的情況下讀取所有貨幣:

    public void ApiCall()
    {
        bool today = false;
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        Tools.Log("Start processing file: " + cf.rateUrl);
        XmlWriter writer = XmlWriter.Create(cf.outXml);
        writer.WriteStartDocument();

        //*** FOR TESTS ***
        using (XmlReader reader = XmlReader.Create(new StreamReader("LastA.xml", Encoding.GetEncoding(28592))))
        //*** FOR TESTS ***            
        //using (XmlReader reader = XmlReader.Create(new StreamReader(WebRequest.Create(cf.rateUrl).GetResponse().GetResponseStream(), Encoding.GetEncoding(28592))))
        {
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (reader.Name.Equals("data_publikacji"))
                        {
                            today = true;
                        }
                        writer.WriteStartElement(reader.Name);
                        while (reader.MoveToNextAttribute())
                        {
                            writer.WriteAttributeString(reader.Name, reader.Value);
                        }
                        break;
                    case XmlNodeType.Text:
                        writer.WriteNode(reader, true);
                        writer.WriteEndElement();
                        if (today)
                        {
                            writer.WriteStartElement("our_date");
                            var settings = new XmlReaderSettings();
                            settings.ConformanceLevel = ConformanceLevel.Fragment;
                            StringReader scontent = new StringReader(string.Format(cf.today.Year + "-" + cf.today.Month + "-" + cf.today.Day));
                            XmlReader ourDate = XmlReader.Create(scontent, settings);
                            writer.WriteNode(ourDate, true);
                            writer.WriteEndElement();
                            today = false;
                        }
                        break;
                    case XmlNodeType.EndElement:
                        writer.WriteNode(reader, false);
                        break;
                }
            }
        }
        writer.WriteEndDocument();
        writer.Close();
    }

您可以使用 XPath 表達式,僅選擇“kod_waluty”匹配允許貨幣列表的節點,簡而言之:

xmlDoc.SelectNodes("//pozycja[contains('THB', kod_waluty)]"))

如果您使用這個小提琴,我相信您將能夠使其適應您的需要! https://dotnetfiddle.net/jv98UZ (鏈接於 11 月 17 日更新)

注意該示例僅匹配一種貨幣,但您可以在如下列表中輸入更多代碼 (XXX YYY ZZZ):

xmlDoc.SelectNodes("//pozycja[contains('THB XXX YYY ZZZ', kod_waluty)]"))

編輯:如果您真的喜歡示例中的流程並希望盡可能少地更改,而不是直接寫入您的 XmlWriter“編寫器”,您可以寫入一個臨時對象(也許是 XmlNode?),然后一旦您驗證您可以將臨時對象寫入“writer”,或者在它無效時忽略它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM