Java文件操作①——XML文件的讀取

来源:http://www.cnblogs.com/Qian123/archive/2016/07/12/5231303.html
-Advertisement-
Play Games

一、邂逅XML 文件種類是豐富多彩的,XML作為眾多文件類型的一種,經常被用於數據存儲和傳輸。所以XML在現今應用程式中是非常流行的。本文主要講Java解析和生成XML。用於不同平臺、不同設備間的數據共用通信。 XML文件的表現:以“.xml”為文件擴展名的文件; 存儲結構:樹形結構; 節點名稱區分 ...


一、邂逅XML

文件種類是豐富多彩的,XML作為眾多文件類型的一種,經常被用於數據存儲和傳輸。所以XML在現今應用程式中是非常流行的。本文主要講Java解析和生成XML。用於不同平臺、不同設備間的數據共用通信。

XML文件的表現:以“.xml”為文件擴展名的文件;

   存儲結構:樹形結構;

 

節點名稱區分大小寫。

1、<book id="1"></book> id為屬性, <book><id>1</id></book> id為節點
2、xml文件開頭要加上版本信息和編碼方式<?xml version="1.0" encoding="UTF-8"?>

 比如:

❤ 為什麼要使用XML?

思考1:不同應用程式之間的通信?

思考2:不同平臺間的通信?

思考3:不同平臺間的數據共用?

答案就是我們要學習的XML文件。我們可以使用相同的xml把不同的文件聯繫起來

二、應用 DOM 方式解析 XML

❤ 在Java程式中如何獲取XML文件的內容

解析的目的:獲取節點名、節點值、屬性名、屬性值;

四種解析方式:DOM、SAX、DOM4J、JDOM 

DOM、SAX :java 官方方式,不需要下載jar包
DOM4J、JDOM :第三方,需要網上下載jar包

示例:解析XML文件,目標是解析XML文件後,Java程式能夠得到xml文件的所有數據

思考:如何在Java程式中保留xml數據的結構?

 

如何保留節點之間的層級關係?

註意常用的節點類型:

 下麵介紹DOM方式解析XML:

 功能說明:

代碼示例:

 1 package com.study.domtest;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.xml.parsers.DocumentBuilder;
 6 import javax.xml.parsers.DocumentBuilderFactory;
 7 import javax.xml.parsers.ParserConfigurationException;
 8 
 9 import org.w3c.dom.Document;
10 import org.w3c.dom.NamedNodeMap;
11 import org.w3c.dom.Node;
12 import org.w3c.dom.NodeList;
13 import org.xml.sax.SAXException;
14 
15 /**
16  * DOM方式解析xml
17  */
18 public class DOMTest {
19 
20     public static void main(String[] args) {
21         //1、創建一個DocumentBuilderFactory的對象
22         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
23         //2、創建一個DocumentBuilder的對象
24         try {
25             //創建DocumentBuilder對象
26             DocumentBuilder db = dbf.newDocumentBuilder();
27             //3、通過DocumentBuilder對象的parser方法載入books.xml文件到當前項目下
28             /*註意導入Document對象時,要導入org.w3c.dom.Document包下的*/
29             Document document = db.parse("books.xml");//傳入文件名可以是相對路徑也可以是絕對路徑
30             //獲取所有book節點的集合
31             NodeList bookList = document.getElementsByTagName("book");
32             //通過nodelist的getLength()方法可以獲取bookList的長度
33             System.out.println("一共有" + bookList.getLength() + "本書");
34             //遍歷每一個book節點
35             for (int i = 0; i < bookList.getLength(); i++) {
36                 System.out.println("=================下麵開始遍歷第" + (i + 1) + "本書的內容=================");
37         //❤未知節點屬性的個數和屬性名時:
38                 //通過 item(i)方法 獲取一個book節點,nodelist的索引值從0開始
39                 Node book = bookList.item(i);
40                 //獲取book節點的所有屬性集合
41                 NamedNodeMap attrs = book.getAttributes();
42                 System.out.println("第 " + (i + 1) + "本書共有" + attrs.getLength() + "個屬性");
43                 //遍歷book的屬性
44                 for (int j = 0; j < attrs.getLength(); j++) {
45                     //通過item(index)方法獲取book節點的某一個屬性
46                     Node attr = attrs.item(j);
47                     //獲取屬性名
48                     System.out.print("屬性名:" + attr.getNodeName());
49                     //獲取屬性值
50                     System.out.println("--屬性值" + attr.getNodeValue());
51                 }
52           //❤已知book節點有且只有1個id屬性:
53              /* 
54               //前提:已經知道book節點有且只能有1個id屬性
55               //將book節點進行強制類型轉換,轉換成Element類型
56               Element book1 = (Element) bookList.item(i);
57               //通過getAttribute("id")方法獲取屬性值
58               String attrValue = book1.getAttribute("id");
59               System.out.println("id屬性的屬性值為" + attrValue);
60               */
61                 
62              //解析book節點的子節點
63                 NodeList childNodes = book.getChildNodes();
64               //遍歷childNodes獲取每個節點的節點名和節點值
65                 System.out.println("第" + (i+1) + "本書共有" + childNodes.getLength() + "個子節點");
66                 for (int k = 0; k < childNodes.getLength(); k++) {
67                   //區分出text類型的node以及element類型的node
68                     if(childNodes.item(k).getNodeType() == Node.ELEMENT_NODE){
69                       //獲取了element類型節點的節點名
70                         System.out.print("第" + (k + 1) + "個節點的節點名:" + childNodes.item(k).getNodeName());
71                       //獲取了element類型節點的節點值
72                         System.out.println("--節點值是:" + childNodes.item(k).getFirstChild().getNodeValue());
73 //                        System.out.println("--節點值是:" + childNodes.item(k).getTextContent());
74                     }
75                 }
76                 System.out.println("======================結束遍歷第" + (i + 1) + "本書的內容=================");
77             }
78 
79         } catch (ParserConfigurationException e) {
80             e.printStackTrace();
81         } catch (SAXException e) {
82             e.printStackTrace();
83         } catch (IOException e) {
84             e.printStackTrace();
85         }
86     }
87 
88 }

 三、應用 SAX 方式解析 XML

SAX是SIMPLE API FOR XML的縮寫,與DOM比較而言,SAX是一種輕量型的方法。

Dom解析會將整個xml文件載入到記憶體中,然後再逐個解析
Sax解析是通過Handler處理類逐個依次解析每個節點

在處理DOM的時候,我們需要讀入整個的XML文檔,然後在記憶體中創建DOM樹,生成DOM樹上的每個NODE對象。當文檔比較小的時候,這不會造成什麼問題,但是一旦文檔大起來,處理DOM就會變得相當費時費力。特別是其對於記憶體的需求,也將是成倍的增長,以至於在某些應用中使用DOM是一件很不划算的事。這時候,一個較好的替代解決方法就是SAX。 SAX在概念上與DOM完全不同。首先,不同於DOM的文檔驅動,它是事件驅動的,也就是說,它並不需要讀入整個文檔,而文檔的讀入過程也就是SAX的解析過程。所謂事件驅動,是指一種基於回調(callback)機制的程式運行方法。在XMLReader接受XML文檔,在讀入XML文檔的過程中就進行解析,也就是說讀入文檔的過程和解析的過程是同時進行的,這和DOM區別很大。

❤ 

代碼示例:Book實體類

 1 package com.study.saxtest.entity;
 2 
 3 /**
 4  * 用Book實體類代表XML文件中的"<book>...</book>"中整個元素
 5  * 在遇到<book>標簽,證明我們要存儲新的book時需要創建Book對象
 6  */
 7 public class Book {
 8     private String id;
 9     private String name;
10     private String author;
11     private String year;
12     private String price;
13     private String language;
14     public String getId() {
15      return id;
16     }
17     public void setId(String id) {
18      this.id = id;
19     }
20     public String getName() {
21      return name;
22     }
23     public void setName(String name) {
24      this.name = name;
25     }
26     public String getAuthor() {
27      return author;
28     }
29     public void setAuthor(String author) {
30      this.author = author;
31     }
32     public String getYear() {
33      return year;
34     }
35     public void setYear(String year) {
36      this.year = year;
37     }
38     public String getPrice() {
39      return price;
40     }
41     public void setPrice(String price) {
42      this.price = price;
43     }
44     public String getLanguage() {
45      return language;
46     }
47     public void setLanguage(String language) {
48      this.language = language;
49     }
50 }

SAXParserHandler類:

  1 package com.study.saxtest.handler;
  2 
  3 import java.util.ArrayList;
  4 
  5 import org.xml.sax.Attributes;
  6 import org.xml.sax.SAXException;
  7 import org.xml.sax.helpers.DefaultHandler;
  8 
  9 import com.study.saxtest.entity.Book;
 10 
 11 public class SAXParserHandler extends DefaultHandler{
 12     /*註意DefaultHandler是org.xml.sax.helpers包下的*/
 13     
 14     int bookIndex = 0;//設置全局變數,用來記錄是第幾本書
 15     
 16     String value = null;
 17     Book book = null;
 18     private ArrayList<Book> bookList = new ArrayList<Book>();//保存book對象
 19 
 20     public ArrayList<Book> getBookList() {
 21         return bookList;
 22     }
 23 
 24     /**
 25      * 用來標識解析開始
 26      */
 27     @Override
 28     public void startDocument() throws SAXException {
 29         super.startDocument();
 30         System.out.println("SAX解析開始");
 31 
 32     }
 33     
 34     /**
 35      * 用來標識解析結束
 36      */
 37     @Override
 38     public void endDocument() throws SAXException {
 39         super.endDocument();
 40         System.out.println("SAX解析結束");
 41     }
 42     
 43     /**
 44      * 用來遍歷xml文件的開始標簽
 45      * 解析xml元素
 46      */
 47     @Override
 48     public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
 49         //調用DefaultHandler類的startElement方法
 50         super.startElement(uri, localName, qName, attributes);
 51         if (qName.equals("book")) {
 52             bookIndex++;
 53             //創建一個book對象
 54             /*Book*/ book = new Book();
 55             //開始解析book元素的屬性
 56             System.out.println("======================開始遍歷第"+bookIndex+"本書的內容=================");
 57            /* //❤已知節點的屬性名時:比如已知id屬性,根據屬性名稱獲取屬性值
 58             String value = attributes.getValue("id");
 59             System.out.print("book的屬性值是:"+value);*/
 60           //❤未知節點的屬性名時,獲取屬性名和屬性值
 61             int num=attributes.getLength();
 62             for(int i=0;i<num;i++){
 63                 System.out.print("book元素的第"+(i+1)+"個屬性名是:"+attributes.getQName(i));
 64                 System.out.println("---屬性值是:"+attributes.getValue(i));
 65                 if (attributes.getQName(i).equals("id")) {//往book對象中塞值
 66                     book.setId(attributes.getValue(i));
 67                 }
 68             }
 69         }else if (!qName.equals("book") && !qName.equals("bookstore")) {
 70             System.out.print("節點名是:" + qName + "---");//此時qName獲取的是節點名(標簽)
 71         }
 72     }
 73     
 74     /**
 75      * 用來遍歷xml文件的結束標簽
 76      */
 77     @Override
 78     public void endElement(String uri, String localName, String qName) throws SAXException {
 79         //調用DefaultHandler類的endElement方法
 80         super.endElement(uri, localName, qName);
 81         //判斷是否針對一本書已經遍歷結束
 82         if (qName.equals("book")) {
 83             bookList.add(book);//在清空book對象之前先保存
 84             book = null;//把book清空,方便解析下一個book節點
 85             System.out.println("======================結束遍歷第"+bookIndex+"本書的內容=================");
 86         }else if (qName.equals("name")) {
 87             book.setName(value);
 88         }
 89         else if (qName.equals("author")) {
 90          book.setAuthor(value);
 91         }
 92         else if (qName.equals("year")) {
 93          book.setYear(value);
 94         }
 95         else if (qName.equals("price")) {
 96          book.setPrice(value);
 97         }
 98         else if (qName.equals("language")) {
 99          book.setLanguage(value);
100         }
101     }
102     
103     /**
104      * 獲取文本
105      * 重寫charaters()方法時,
106      * String(byte[] bytes,int offset,int length)的構造方法進行數組的傳遞
107      * 去除解析時多餘空格
108      */
109     @Override
110     public void characters(char[] ch, int start, int length)throws SAXException {
111         /**
112          * ch 代表節點中的所有內容,即每次遇到一個標簽調用characters方法時,數組ch實際都是整個XML文檔的內容
113          * 如何每次去調用characters方法時我們都可以獲取不同的節點屬性?這時就必須結合start(開始節點)和length(長度)
114          */
115         super.characters(ch, start, length);
116         /*String */value = new String(ch, start, length);//value獲取的是文本(開始和結束標簽之間的文本)
117 //        System.out.println(value);//輸出時會多出兩個空格,是因為xml文件中空格與換行字元被看成為一個文本節點
118         if(!value.trim().equals("")){//如果value去掉空格後不是空字元串
119             System.out.println("節點值是:" + value);
120         }
121     }
122     
123     /**
124      * qName獲取的是節點名(標簽)
125      * value獲取的是文本(開始和結束標簽之間的文本)
126      * 思考:qName和value分別在兩個方法中,如何將這兩個方法中的參數整合到一起?
127      * 分析:要在兩個方法中用同一個變數,就設置成全局變數,可以賦初值為null。
128      *     可以把characters()方法中的value作成一個全局變數
129      * 
130      * 然後在endElement()方法中對book對象進行塞值。記得要把Book對象設置為全局變數,變數共用
131      */
132 }

測試類:SAXTest

 1 package com.study.saxtest.test;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.xml.parsers.ParserConfigurationException;
 6 import javax.xml.parsers.SAXParser;
 7 import javax.xml.parsers.SAXParserFactory;
 8 
 9 import org.xml.sax.SAXException;
10 
11 import com.study.saxtest.entity.Book;
12 import com.study.saxtest.handler.SAXParserHandler;
13 
14 /**
15  * sax方式解析XML
16  */
17 public class SAXTest {
18 
19     public static void main(String[] args) {
20         //1.獲取一個SAXParserFactory的實例對象
21         SAXParserFactory factory = SAXParserFactory.newInstance();
22         //2.通過factory的newSAXParser()方法獲取一個SAXParser類的對象。
23         try {
24             SAXParser parser = factory.newSAXParser();
25             //創建SAXParserHandler對象
26             SAXParserHandler handler = new SAXParserHandler();
27             parser.parse("books.xml", handler);
28             System.out.println("~~~~~共有"+handler.getBookList().size()+"本書");
29             for (Book book : handler.getBookList()) {
30                 System.out.println(book.getId());
31                 System.out.println(book.getName());
32                 System.out.println(book.getAuthor());
33                 System.out.println(book.getYear());
34                 System.out.println(book.getPrice());
35                 System.out.println(book.getLanguage());
36                 System.out.println("----finish----");
37             }
38         } catch (ParserConfigurationException e) {
39             e.printStackTrace();
40         } catch (SAXException e) {
41             e.printStackTrace();
42         } catch (IOException e) {
43             e.printStackTrace();
44         }
45     }
46 
47 }

 運行結果:

SAX解析開始
======================開始遍歷第1本書的內容=================
book元素的第1個屬性名是:id---屬性值是:1
節點名是:name---節點值是:冰與火之歌
節點名是:author---節點值是:喬治馬丁
節點名是:year---節點值是:2014
節點名是:price---節點值是:89
======================結束遍歷第1本書的內容=================
======================開始遍歷第2本書的內容=================
book元素的第1個屬性名是:id---屬性值是:2
節點名是:name---節點值是:安徒生童話
節點名是:year---節點值是:2004
節點名是:price---節點值是:77
節點名是:language---節點值是:English
======================結束遍歷第2本書的內容=================
SAX解析結束
~~~~~共有2本書
1
冰與火之歌
喬治馬丁
2014
89
null
----finish----
2
安徒生童話
null
2004
77
English
----finish----
View Code

 四、應用 DOM4J 及 JDOM 方式解析 XML

 # JDOM 方式解析 XML

  JDOM 開始解析前的準備工作:

  JDOM是第三方提供的解析XML方法,需要jdom-2.0.5.jar包

 

 示例代碼:

  1 package com.study.jdomtest1.test;
  2 
  3 import java.io.FileInputStream;
  4 import java.io.FileNotFoundException;
  5 import java.io.IOException;
  6 import java.io.InputStream;
  7 import java.io.InputStreamReader;
  8 import java.util.ArrayList;
  9 import java.util.List;
 10 
 11 import org.jdom2.Attribute;
 12 import org.jdom2.Document;
 13 import org.jdom2.Element;
 14 import org.jdom2.JDOMException;
 15 import org.jdom2.input.SAXBuilder;
 16 
 17 import com.study.jdomtest1.entity.Book;
 18 
 19 /**
 20  *  JDOM 解析XML
 21  */
 22 public class JDOMTest {
 23     private static ArrayList<Book> booksList = new ArrayList<Book>();
 24 
 25     public static void main(String[] args) {
 26         // 進行對books.xml文件的JDOM解析
 27         //❤準備工作
 28         // 1.創建一個SAXBuilder的對象
 29         SAXBuilder saxBuilder = new SAXBuilder();//註意SAXBuilder是org.jdom2.input包下的
 30         InputStream in;
 31         try {
 32             // 2.創建一個輸入流,將xml文件載入到輸入流中
 33             in=new FileInputStream("books.xml");//如果將xml文件放在src/res包下,此時應該輸入“src/res/books.xml”
 34             InputStreamReader isr = new InputStreamReader(in, "UTF-8");//使用包裝流InputStreamReader進行讀取編碼的指定,防止亂碼
 35             // 3.通過saxBuilder的build方法,將輸入流載入到saxBuilder中
 36             Document document = saxBuilder.build(isr);
 37             // 4.通過document對象獲取xml文件的根節點
 38             Element rootElement = document.getRootElement();
 39             // 5.獲取根節點下的子節點的List集合
 40             List<Element> bookList = rootElement.getChildren();
 41             //❤ 繼續解析,採用for迴圈對bookList進行遍歷
 42             for (Element book : bookList) {
 43                 Book bookEntity = new Book();
 44                 System.out.println("======開始解析第" + (bookList.indexOf(book) + 1) + "書======");//indexOf()返回的是index的位置,是從0開始
 45                 // 解析book的屬性集合
 46                 List<Attribute> attrList = book.getAttributes();//適用於未知屬性情況下
 47                 /*//知道節點下屬性名稱時,獲取節點值
 48                 book.getAttributeValue("id");*/
 49                 // 遍歷attrList(針對不清楚book節點下屬性的名字及數量)
 50                 for (Attribute attr : attrList) {
 51                     /**註:JDom中,Attribute的getName和getValue方法獲取到的都是實際的名稱和值,
 52                      * 不會出現SAX和DOM中的空格和換行的情況*/
 53                     // 獲取屬性名
 54                     String attrName = attr.getName();
 55                     // 獲取屬性值
 56                     String attrValue = attr.getValue();
 57                     System.out.println("屬性名:" + attrName + "----屬性值:" + attrValue);
 58                     if (attrName.equals("id")) {
 59                         bookEntity.setId(attrValue);
 60                        }
 61                 }
 62                 
 63                 //❤對book節點的子節點的節點名以及節點值的遍歷
 64                 List<Element> bookChilds = book.getChildren();
 65                 for (Element child : bookChilds) {
 66                     System.out.println("節點名:" + child.getName() + "----節點值:" + child.getValue());
 67                     if (child.getName().equals("name")) {
 68                         bookEntity.setName(child.getValue());
 69                        }
 70                        else if (child.getName().equals("author")) {
 71                         bookEntity.setAuthor(child.getValue());
 72                        }
 73                        else if (child.getName().equals("year")) {
 74                         bookEntity.setYear(child.getValue());
 75                        }
 76                        else if (child.getName().equals("price")) {
 77                         bookEntity.setPrice(child.getValue());
 78                        }
 79                        else if (child.getName().equals("language")) {
 80                         bookEntity.setLanguage(child.getValue());
 81                        }
 82 
 83                 }
 84                 System.out.println("======結束解析第" + (bookList.indexOf(book) + 1) + "書======");
 85                 booksList.add(bookEntity);
 86                 bookEntity = null;
 87                 //測試數據
 88                 System.out.println(booksList.size());
 89        

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在eclipse中新建web項目,集成spring開發環境,把集成spring的過程描述如下, 1、從spring官網下載spring的jar包,我這裡是spring4.1,下載的文件中包含了源碼及文檔,我們挑選出需要的jar包,一共20個,為了方便我們可以把20個jar全部放進lib目錄下 2、在 ...
  • 看到很多的開源資料庫會用到MySQL,Python同樣也使用,但是我已經習慣使用圖形化界面,操作感極強的MS-SQL 看到Python也提供MS-SQL連接方式,需要用到PyMssql。 在Windows DOS CMD命令中 輸入: 關於pymssql文檔鏈接 http://pymssql.org ...
  • 轉自:http://www.cnblogs.com/shenliang123/p/3344555.html 在項目中總會遇到一些關於載入的優先順序問題,剛剛就遇到了一個問題,由於項目中使用了quartz任務調度,quartz在web.xml中是使用listener進行監聽的,使得在tomcat啟動的時 ...
  • golang提供了goroutine快速實現併發編程,在實際環境中,如果goroutine中的代碼要消耗大量資源時(CPU、記憶體、帶寬等),我們就需要對程式限速,以防止goroutine將資源耗盡。下麵我們討論兩種對goroutine限速的實現方法。 ...
  • ...
  • php從入門到放棄系列-01.php環境的搭建 一、為什麼要學習php 1、php語言適用於中小型網站的快速開發; 2、並且有非常成熟的開源框架,例如yii,thinkphp等; 3、幾乎全部的CMS內容管理系統,例如織夢,discuz,帝國,江湖等,採用php語言,而CMS內容管理系統,發展勢頭良 ...
  • 在上面的例子中,我們看到了WebDriver的一些方法,今天列舉WebDriver的Get方法: ...
  • 1.Raneto Docs簡單說明 a Raneto是一個基於Markdown的開源的node.js知識庫平臺,它使用Markdown文件來存儲知識庫,Raneto我們也可以將其稱之為"靜態網站生成器",因為它不需要資料庫存儲數據,所有的內容都是存儲在Markdown(.md)文件中,他擁有以下幾個 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...