JDOM 操作XML

来源:http://www.cnblogs.com/kungfupanda/archive/2017/07/25/7232009.html
-Advertisement-
Play Games

http://www.cnblogs.com/hoojo/archive/2011/08/11/2134638.html 可擴展標記語言——eXtensible Markup Language 用戶可以自己定義語言標記,只要有開始和閉合標簽即可。 xsl裝飾、修飾xml的顯示結果。 dtd約束xml ...


http://www.cnblogs.com/hoojo/archive/2011/08/11/2134638.html

可擴展標記語言——eXtensible Markup Language

用戶可以自己定義語言標記,只要有開始和閉合標簽即可。

xsl裝飾、修飾xml的顯示結果。

dtd約束xml文件中的標記。

Ø XML的優點:

    1、xml可以讓數據和標記分離。

    2、異質信息互通

    3、機器語言

    4、用交流語言替代html裝飾語言

    5、簡單易用

    6、可以自定義、可擴展  

Ø XML和HTML比較

比較內容

HTML

XML

可擴展性

不具有擴展性、標記固定

是元標記語言,可以定義新標記,用戶可以自定義標記

側重點

側重於信息的表現形式為什麼格式被關註

側重於結構化的描述信息,數據是什麼為XML所關註

語法

不嚴格(嵌套、配對)

嚴格嵌套、配對,並按照DTD要求輸出

可讀性、可維護性

難於閱讀和維護

結構清晰,便於閱讀維護

數據本身、顯示

數據和顯示合為一處

數據與顯示分離

重用性

可重用性高

 

Ø JDOM操作XML

JDOM可以很方便的操作XML文檔,完成XML內容的創建、修改,已經遍歷Document文檔中的XML元素,完成查詢等。下麵我們就用JDOM完成這些功能。

# 準備

首先我們要準備jdom相關的jar包

jdom-jar下載地址:http://www.jdom.org/dist/binary/

jaxen在jdom的zip壓縮包中可以找到。

Junit是測試用的,可以不添加。但需要用main方法測試。

Junit-jarhttp://ebr.springsource.com/repository/app/bundle/version/download?name=com.springsource.org.junit&version=4.8.1&type=binary  

 

其次,是準備測試工作。部分測試代碼:

package com.hoo.test;
 
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.jdom.Attribute;
import org.jdom.Comment;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.Text;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
 
/**
 * <b>function:</b> JDOM操作XML
 * @author hoojo
 * @createDate 2011-8-4 下午12:34:09
 * @file DocumentTest.java
 * @package com.hoo.test
 * @project JDOMTest
 * @blog http://blog.csdn.net/IBM_hoojo
 * @email [email protected]
 * @version 1.0
 */
public class DocumentTest {
    
    private XMLOutputter out = null;
    
    @Before
    public void init() {
        //輸出文件信息
        out = new XMLOutputter();
    }
    
    @After
    public void destory() {
        if (out != null) {
            out = null;
        }
        System.gc();
    }
    
    /**
     * <b>function:</b>輸出Document文檔信息
     * @author hoojo
     * @createDate 2011-8-5 下午12:10:27
     * @param doc
     */
    private void print(Document doc) {
        //設置XML文件編碼格式
        //out.setFormat(Format.getCompactFormat().setEncoding("gb2132"));
        System.out.println(out.outputString(doc));
    }
    
    private void fail(Object o) {
        if (o != null) {
            System.out.println(o);
        }
    }
}
 

# 創建Document

/**
 * 創建xml元素
 */
@Test
public void createDoc() {
    Document doc = null;
    //method 1、創建一個Doc文檔,添加一個元素root
    doc = new Document(new Element("root"));
    print(doc);
    
    //method 2、創建一個Doc文檔,添加一個元素root,設置root元素的節點文本
    doc = new Document(new Element("root").setText("this is a root el"));
    print(doc);
    
    //method 3、創建一個Doc文檔,添加一個元素root,設置root元素的節點文本且添加一個屬性id,值為110
    Element root = new Element("root");
    root.setText("this is a root el");
    root.setAttribute("id", "110");
    doc.setRootElement(root);
    fail("method 3: \n" + out.outputString(doc));
    
    //method 4、創建一個Doc文檔,添加一個元素root,設置root元素的節點文本
    doc = new Document();
    doc.addContent(new Element("root").setText("this is a root el"));
    fail("method 4: \n" + out.outputString(doc));
    
    fail(doc.toString());
}

* new Document可以創建一個doc文檔

當給Document傳遞一個Element參數時,這個Element就是根元素;

當調用Document的setRootElement方法時,可以設置當前Doc的根元素;

當調用doc的addContent的時候,添加的元素將會是根元素;

doc = new Document(new Element("root").setText("this is a root el"));

上面就創建了一個doc,根元素是root,root節點的內容是this is a root el;

註意setText方法返回的對象是當前Element,類似是StringBuffer的append方法; 

 

* new Element()可以創建一個元素

如果傳遞參數那麼這個參數將會是元素節點的名稱;

Element的setText方法可以設置元素的文本值;

Element root = new Element("root");
root.setText("this is a root el");

創建一個節點名稱為root的元素,文本是this is a root el

 

* setAttribute()可以設置某個具體節點的屬性值

root.setAttribute("id", "110");

給root節點添加一個id,值為110

 

* addContent添加註釋

root .addContent(new Comment("註釋"));

在root元素下添加一個註釋;

addContent是向元素中添加內容,而setContent是設置內容;

 

* setText設置元素文本內容

root.setText("this is a root el");
同樣
root. setContent(new Text("this is text"))
同樣
root.addContent("this is text");

下麵用上面的這些方法,創建一篇XML文檔。文檔內容如下:

/**
    創建一遍xml文檔
    <?xml version="1.0" encoding="UTF-8"?>
    <car vin="123fhg5869705iop90">
      <!--Description of a car-->
      <make>Toyota</make>
      <model>Celica</model>
      <year>1997</year>
      <color>green</color>
      <license state="CA">1ABC234</license>
    </car>
 */
@Test
public void createXMLDoc() {
    //創建一個car的元素
    Element carEl = new Element("car");
    //創建vin屬性,並設置值
    carEl.setAttribute("vin", "123fhg5869705iop90");
    
    //創建註釋
    carEl.addContent(new Comment("Description of a car"));
    
    //創建一個make元素,設置文本內容
    carEl.addContent(new Element("make").setText("Toyota"));
    
    //創建一個model元素,添加一個文本元素
    carEl.addContent(new Element("model").setContent(new Text("Celica")));
    
    //創建一個year元素,添加文本內容
    carEl.addContent(new Element("year").addContent("1997"));
    
    //創建一個color元素,文本內容是green
    carEl.addContent(new Element("color").setText("green"));
    
    //創建一個license的元素
    Element licenseEl = new Element("license");
    //為license元素添加文本內容
    licenseEl.addContent("1ABC234");
    //創建一個state的屬性,值為CA
    licenseEl.setAttribute("state", "CA");
    //將licenseEl添加到根元素中
    carEl.addContent(licenseEl);
    
    //將car元素設置為根元素
    Document doc = new Document(carEl);
    print(doc);
    /*out = new XMLOutputter();
    try {
        out.output(doc, System.out);
    } catch (IOException e) {
        e.printStackTrace();
    }*/
}

方法運行後,所創建的文檔和上面註釋文檔內容相同

 

# 讀取XML文件的內容

disk.xml文件內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<HD>
    <disk name="C">
        <capacity>8G</capacity>
        <directories>200</directories>
        <files>1580</files>
    </disk>
    <disk name="D">
        <capacity>10G</capacity>
        <directories>500</directories>
        <files>3000</files>
    </disk>
    <disk2 name="E">
        <capacity>11G</capacity>
        <directories>50</directories>
        <files size="200" modifyDate="2011-08-3">
            <file>Java book</file>
            <file>Spring.txt</file>
            <file>strtus.doc</file>
        </files>
    </disk2>
    <files size="220">500</files>
</HD>

讀取disk文件的內容,代碼如下:

/**
 * <b>function:</b>讀取xml文件中的元素
 * @author hoojo
 * @createDate 2011-8-4 下午04:54:17
 */
@Test
@SuppressWarnings("unchecked")
public void readXMLContent() {
    SAXBuilder builder = new SAXBuilder();
    try {
        Document doc = builder.build(new File("file/disk.xml"));
        Element rootEl = doc.getRootElement();
        //獲得所有子元素
        List<Element> list = rootEl.getChildren();
        //List<Element> list = rootEl.getChildren("disk");
        for (Element el : list) {
            //獲取name屬性值
            String name = el.getAttributeValue("name");
            //獲取子元素capacity文本值
            String capacity = el.getChildText("capacity");
            //獲取子元素directories文本值
            String directories = el.getChildText("directories");
            String files = el.getChildText("files");
            System.out.println("磁碟信息:");
            System.out.println("分區盤符:" + name);
            System.out.println("分區容量:" + capacity);
            System.out.println("目錄數:" + directories);
            System.out.println("文件數:" + files);
            System.out.println("-----------------------------------");
        }
    } catch (JDOMException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

* getChildren方法可以獲取所有子元素

* getChildren(elName)可以獲取所有名稱為elName的子節點

* getAttributeValue可以獲取指定屬性的值

* getChildText可以獲取子節點的文本值

 

# 遞歸顯示文檔信息

/**
 * 遞歸返回指定格式的“--”
 */
private String format(int i) {
    String temp = "";
    if (i > 0) {
        temp += "--";
        i--;
        temp += format(i);
    }
    return temp;
}
 
/**
 * <b>function:</b>顯示當前節點所有Element的屬性信息
 * @author hoojo
 * @createDate 2011-8-4 下午06:10:53
 * @param el
 * @return
 */
@SuppressWarnings("unchecked")
private String getAttrInfo(Element el) {
    List<Attribute> attrs = el.getAttributes();
    return getAttrInfo(attrs);
}
 
/**
 * <b>function:</b>顯示屬性信息
 * @author hoojo
 * @createDate 2011-8-9 下午03:52:59
 * @param attrs
 * @return
 */
private String getAttrInfo(List<Attribute> attrs) {
    StringBuilder info = new StringBuilder();
    for (Attribute attr : attrs) {
        info.append(attr.getName()).append("=").append(attr.getValue()).append(", ");
    }
    if (info.length() > 0) {
        return "[" + info.substring(0, info.length() - 2)+ "]";
    }
    return "";
}
 
/**
 * <b>function:</b>遞歸顯示文檔節點元素信息
 * @author hoojo
 * @createDate 2011-8-4 下午05:56:34
 * @param i
 * @param list
 */
@SuppressWarnings("unchecked")
private void print(int i, List<Element> list) {
    i++;
    for (Element el : list) {
        List<Element> childs = el.getChildren();
        if (childs.size() > 0) {
            fail(format(i) + el.getName() + "  " + getAttrInfo(el));
            print(i, childs);
        } else {
            fail(format(i) + el.getName() + ":" + el.getText() + "  " + getAttrInfo(el));
        }
    }
}

調用print(0, root.getChildren());方法就可以看到一篇格式化後輸出的文檔內容

#############顯示文檔信息###############
--HD
----disk [name=C]
------capacity:8G
------directories:200
------files:1580
----disk [name=D]
------capacity:10G
------directories:500
------files:3000
----disk2 [name=E]
------capacity:11G
------directories:50
------files [size=200, modifyDate=2011-08-3]
--------file:Java book
--------file:Spring.txt
--------file:strtus.doc
----files:500 [size=220]

 

# XPath查詢遍歷XML文檔

/**
 * <b>function:</b>用xpath遍歷xml信息
 * @author hoojo
 * @createDate 2011-8-4 下午04:56:52
* xpath參考:http://www.w3school.com.cn/xpath/xpath_functions.asp
 * 
 *     nodeName 選取此節點的所有子節點 
    /    從根節點選取 
    //   從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的 
    .    選取當前節點 
    ..   選取當前節點的父節點 
    @  選取屬性 
    
    * 匹配任何元素節點 
    @* 匹配任何屬性節點 
    node() 配任何類型的節點 
    
    ancestor 選取當前節點的所有先輩(父、祖父等) 
    ancestor-or-self 選取當前節點的所有先輩(父、祖父等)以及當前節點本身 
    attribute 選取當前節點的所有屬性 
    child 選取當前節點的所有子元素。 
    descendant 選取當前節點的所有後代元素(子、孫等)。 
    descendant-or-self 選取當前節點的所有後代元素(子、孫等)以及當前節點本身。 
    following 選取文檔中當前節點的結束標簽之後的所有節點。 
    namespace 選取當前節點的所有命名空間節點 
    parent 選取當前節點的父節點。 
    preceding 選取文檔中當前節點的開始標簽之前的所有節點。 
    preceding-sibling 選取當前節點之前的所有同級節點。 
    self 選取當前節點。
    
    child::book 選取所有屬於當前節點的子元素的 book 節點 
    attribute::languane 選取當前節點的 languange 屬性 
    child::* 選取當前節點的所有子元素 
    attribute::* 選取當前節點的所有屬性 
    child::text() 選取當前節點的所有文本子節點 
    child::node() 選取當前節點的所有子節點 
    descendant::book 選取當前節點的所有 book 後代 
    ancestor::book 選擇當前節點的所有 book 先輩
 */
@SuppressWarnings("unchecked")
@Test
public void queryElementByXPath() {
    SAXBuilder builder = new SAXBuilder();
    try {
        Document doc = builder.build(new File("file/disk.xml"));
        List<Element> list = XPath.selectNodes(doc, "/HD/disk");
        for (Element el : list) {
            String name = el.getAttributeValue("name");
            String capacity = el.getChildText("capacity");
            String directories = el.getChildText("directories");
            String files = el.getChildText("files");
            System.out.println("磁碟信息:");
            System.out.println("分區盤符:" + name);
            System.out.println("分區容量:" + capacity);
            System.out.println("目錄數:" + directories);
            System.out.print("文件數:" + files);
            
            String capacityText = ((Text) XPath.selectSingleNode(el, "//disk[@name='" + name + "']/capacity/text()")).getTextNormalize();
            System.out.println("#" + capacityText);
            
            System.out.println("-----------------------------------");
        }
        //顯示文檔信息
        System.out.println("#############顯示文檔信息###############");
        print(0, doc.getContent());
        
        //獲得hd元素
        System.out.println("#############顯示HD子元素信息###############");
        Element root = (Element) XPath.selectSingleNode(doc, "/HD");
        //fail(root.getChildren().size());
        print(0, root.getChildren());
        
        //獲取hd下所有元素
        System.out.println("#############顯示HD子元素信息###############");
        List roots = (List) XPath.selectNodes(doc, "/HD/*");
        //fail(roots.size());
        print(0, roots);
        
        //獲得hd下的所有disk元素
        System.out.println("#############顯示disk信息###############");
        roots = (List) XPath.selectNodes(doc, "/HD/disk");
        //fail(roots.size());
        print(0, roots);
        
        System.out.println("#############顯示disk2信息###############");
        roots = (List) XPath.selectNodes(doc, "/HD/disk2");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的files信息###############");
        roots = (List) XPath.selectNodes(doc, "//files");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的files指定下標的file信息###############");
        roots = (List) XPath.selectNodes(doc, "//files/file[1]");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的files最後的file信息###############");
        roots = (List) XPath.selectNodes(doc, "//files/file[last()]");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的files倒數第二的file信息###############");
        roots = (List) XPath.selectNodes(doc, "//files/file[last() - 1]");
        print(0, roots);
 
        System.out.println("#############顯示任意路徑下的files的子元素file位置position在第二的file信息###############");
        roots = (List) XPath.selectNodes(doc, "//files/file[position() = 2]");
        //roots = (List) XPath.selectNodes(doc, "//files/file[position() > 2]");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的files第三個file的當前節點的前面所有同級節點信息###############");
        roots = (List) XPath.selectNodes(doc, "//files/file[3]/preceding-sibling::*");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的disk2之前的所有節點信息###############");
        roots = (List) XPath.selectNodes(doc, "//disk2/preceding::*");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的disk2之後的所有節點信息###############");
        roots = (List) XPath.selectNodes(doc, "//disk2/following::*");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的files的所有屬性信息###############");
        roots = (List) XPath.selectNodes(doc, "//files/attribute::*");
        fail(getAttrInfo(roots));
        
        System.out.println("#############顯示任意路徑下的節點是disk屬性name=C的信息###############");
        roots = (List) XPath.selectNodes(doc, "//disk[@name='C']");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的節點是disk的子元素的文本中含義5和8節點的信息###############");
        roots = (List) XPath.selectNodes(doc, "//disk/child::*[contains(text(), '8') and contains(text(), '5')]");
        //roots = (List) XPath.selectNodes(doc, "//disk/child::*[contains(text(), '8') or contains(text(), '5')]");
        print(0, roots);
 
        System.out.println("#############顯示任意路徑下的節點是files且有屬性size的信息###############");
        roots = (List) XPath.selectNodes(doc, "//files[@size]");
        print(0, roots);
 
        System.out.println("#############顯示HD節點下capacity的值為11G的信息###############");
        //roots = (List) XPath.selectNodes(doc, "/HD/disk/capacity[text()='11G']");
        roots = (List) XPath.selectNodes(doc, "/HD/*/capacity[text()='11G']");
        //roots = (List) XPath.selectNodes(doc, "/*/*/capacity[text()='11G']");
        print(0, roots);
        
        //parent::*表示父節點集合
        System.out.println("#############顯示任意路徑下的節點是files且屬性size有值的父節點的信息###############");
        roots = (List) XPath.selectNodes(doc, "//files[@size='200']/parent::*");
        print(0, roots);
        
        System.out.println("#############顯示任意路徑下的節點disk的子節點的capacity信息###############");
        roots = (List) XPath.selectNodes(doc, "//disk/child::capacity");
        print(0, roots);
        
        //獲取c盤的大小
        System.out.println("獲取c盤的大小");
        Text filesText = (Text) XPath.selectSingleNode(doc, "/HD/disk[@name='C']/files/text()");
        System.out.println(filesText.getTextNormalize());
        
        //XPath function
        /**
        string concat (string, string, string*)  聯接兩個字元串 
        boolean starts-with (string, string)  判斷某字元串是否以另一字元串開頭 
        boolean contains (string, string)  判斷某字元串是否包含另一字元串 
        string substring (string, number, number)  取子字元串 
        number string-length (string)  測字元串長度 
        number sum (node-set)  求和 
        number floor (number)  求小於此數的最大整數值 
        number ceiling (number)  求大於此數最小整數值
        **/ 
 
        System.out.println("獲取@size的和大於200的");
        roots = (List) XPath.selectNodes(doc, "//files[sum(@size) > 200]");
        print(0, roots);
 
        System.out.println("查找directories的內容長度小於3的");
        roots = (List) XPath.selectNodes(doc, "//directories[string-length(text()) < 3]");
        print(0, roots);
        
        System.out.println("查找files的內容包含5的");
        roots = (List) XPath.selectNodes(doc, "//files[contains(text(), '5')]");
        print(0, roots);
    } catch (JDOMException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } 
}

 

# 刪除元素及其他操作

/**
 * <b>function:</b>列印doc相關信息
 * @author hoojo
 * @createDate 2011-8-10 下午06:29:01
 */
@SuppressWarnings("unchecked")
@Test
public void printInfo() {
    SAXBuilder builder = new SAXBuilder();
    try {
        //builder.setFeature("user", true);
        //builder.setIgnoringBoundaryWhitespace(true);
        //忽略元素內容的空格
        //builder.setIgnoringElementContentWhitespace(true);
        
        Document doc = builder.build(new File("file/web.xml"));
        fail("baseURI: " + doc.getBaseURI());
        fail("ContentSize: " + doc.getContentSize());
        //System.out.println("getContent: ");
        //print(0, doc.getContent());
        
        fail("getContent index: " + doc.getRootElement().getContent(1));
        fail("getDocType: " + doc.getDocType());
        fail("getParent: " + doc.getRootElement().getContent(1).getParent());
        fail("getProperty: " + doc.getProperty("filter"));
        print(0, XPath.selectNodes(doc, "//*[contains(text(), '#')]"));
        fail("getText: " + ((Element)XPath.selectNodes(doc, "//*[contains(text(), '#')]").get(0)).getText());
        fail("getTextTrim: " + ((Element)XPath.selectNodes(doc, "//*[contains(text(), '#')]").get(0)).getTextTrim());
        fail("getTextNormalize: " + ((Element)XPath.selectNodes(doc, "//*[contains(text(), '#')]").get(0)).getTextNormalize());
        fail("hasRootElement: " + doc.hasRootElement());
        
        //如果文檔帶有Namespace一定要設置Namespace,不然無法讀取內容
        Namespace ns = Namespace.getNamespace("http://java.sun.com/xml/ns/javaee");
        Element servletEl = doc.getRootElement().getChild("servlet", ns);
        fail("servletEl: " + servletEl);
        print(0, servletEl.getChildren());
        
        fail("getChildText: " + servletEl.getChildText("servlet-class", ns));
        fail("getChildTextNormalize: " + servletEl.getChildTextNormalize("servlet-name", ns));
        fail("getChildTextTrim: " + servletEl.getChildTextTrim("servlet-class", ns));
        fail("getName: " + servletEl.getName());
        fail("getNamespacePrefix: " + servletEl.getNamespacePrefix());
        fail("getNamespace: " + servletEl.getNamespace());
        fail("getQualifiedName: " + servletEl.getQualifiedName());
        Element classEl = servletEl.getChild("servlet-class", ns);
        fail("getText: " + classEl.getText());
        fail("getTextNormalize: " + classEl.getTextNormalize());
        fail("getTextTrim: " + classEl.getTextTrim());
        fail("getValue: " + classEl.getValue());
        
        //刪除節點
        fail(doc.getRootElement().removeContent(3));
        //print(0, doc.removeContent());
        //print(0, doc.getRootElement().getChildren());
        fail(servletEl.removeChild("servlet-class", ns));
        fail(servletEl.removeChildren("init-param", ns));
        
        print(0, servletEl.getChildren());
    } catch (JDOMException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

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

-Advertisement-
Play Games
更多相關文章
  • 話不多說直接上代碼: ...
  • 話不多說直接上代碼 連接字元串: 主體代碼: IMongoModel: 值得註意的是:需引用MongoDB.BSon與MongoDB.Driver VS2017若在引用包後,還是無法找到命名空間,重啟VS即可。 ABCDEFG.GetAppSetting("mongodb"));讀取配置文件 ...
  • ////////HTTPGET HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "GET"; request.ContentType = "text/html;charset=UTF- ...
  • 18位號碼: 15位號碼: ...
  • 目錄 "簡介" "安裝" "主從複製" "備份與恢復" "API" AddOrUpdate GetOrAdd DeleteByPattern SearchKeys TransExcute Subscribe/Publish "命令" Todo Sentinel .NET Core Configura ...
  • 基於 Quartz.NET 實現可中斷的任務 Quartz.NET 是一個開源的作業調度框架,非常適合在平時的工作中,定時輪詢資料庫同步,定時郵件通知,定時處理數據等。 Quartz.NET 允許開發人員根據時間間隔(或天)來調度作業。它實現了作業和觸發器的多對多關係,還能把多個作業與不同的觸發器關 ...
  • 題目背景 二分圖 題目描述 給定一個二分圖,結點個數分別為n,m,邊數為e,求二分圖最大匹配數 輸入輸出格式 輸入格式: 第一行,n,m,e 第二至e+1行,每行兩個正整數u,v,表示u,v有一條連邊 輸出格式: 共一行,二分圖最大匹配 輸入輸出樣例 輸入樣例#1: 1 1 1 1 1 輸出樣例#1 ...
  • 1.攔截器與過濾器的區別 相同點:攔截器其實也是一種過濾器,都用於對請求和響應做攔截進行額外的處理. 不同點:攔截器主要是通過過濾器來調用的,功能實現主要放在攔截器中,而過濾器主要是用來調用攔截器.而且過濾器屬於java web中的概念範疇,而攔截器只有在struts2框架中採用這一概念 2.str ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...