SoFunction
Updated on 2025-04-04

Summary of three ways to parse XML files using Digester

1. Three ways to parse XML files in Digester

Function and dependency jar package

First of all, understand what Digester does? It is a subproject in Commons, apache open source project, and a tool for parsing XML documents. Digester's underlying layer adopts SAX parsing method, which processes it by traversing XML document rules. When you need to parse the information in the XML file into what we need (such as the java class), it is very convenient to use Digester. Without further ado, the jdk version used in this case is 1.6. Simple jar package dependencies are as follows:

  • commons-digester-1.
  • commons-collections-3.2.
  • commons-beanutils-1.7.

2. Key points and difficulties

Key point: Understanding the concept of stack

Difficulty: When using the addObjectCreate() method, an object will be created and many important methods are carried out relative to the top of the stack or the second top of the stack.

like:

addCallMethod(pattern, methodName): call the specified method of the top element of the stack

addCallMethod(pattern, methodName, paramCount): Call the specified method of the top element of the stack, and the number of parameters of the method can be specified.

addCallMethod(pattern, methodName, paramCount, paramTypes): Call the specified method of the top element of the stack, and can specify the number of parameters and type of the method.

3. XML file

<?xml version="1.0" encoding="UTF-8" ?>
<Orders>
    <Order user="Zhang San" date="2008-11-14" price="12279">
    
        <goods >
            <name>IBMnotebook</name>
            <price>8999</price>
            <count>1</count>
            <total_price>8999</total_price>
        </goods>
        
        <goods >
            <name>Yageol Season</name>
            <price>1300</price>
            <count>2</count>
            <total_price>2600</total_price>
        </goods>
    
    </Order>
</Orders>

4. Parses this xml file in different ways

4.1 Parsing through java encoding (javabean storage)

According to the various nodes of this xml file, we can create two javabeans to store parsed information. are respectively the same.

// Order categorypackage ;

import ;
/**
  *: Order category
  * @author ypykip
  *
  */
public class Order {
    private String user;    //The corresponding user attribute in the <Order> tag    private String date;    //The corresponding date attribute in the <Order> tag    private String price;   //The price attribute corresponding to the <Order> tag    //All <good> tags corresponding to <Order> tags    private ArrayList&lt;Goods&gt; goodsList = new ArrayList&lt;Goods&gt;();
    //Omit getter and setter...
    // Add items to order    public void add(Goods goods){
        ().add(goods);
    }
    // Rewrite the toString() method to facilitate observation of results    @Override
    public String toString() {
        return "Order [user=" + user + ", date=" + date + ", price=" + price
                + ", goodsList=" + () + "]";
    }

}
// Product categorypackage ;

package ;

/**
  *:Product category
  * @author ypykip
  *
  */
public class Goods {
    private String id;
    private String name;
    private String price;
    private String count;
    private String total_price;

    //Omit getter and setter...
    @Override
    public String toString() {
        return "Goods [, name=" + name + ", price=" + price
                + ", count=" + count + ", total_price=" + total_price +"]";
    }
}

// Analytical classimport ;
import ;
import ;
import ;

import ;
import ;

import ;
import ;

/**
  * title: parsed through digester
  * @author grk
  * Focus: Understand the concept of stack
  * When using the addObjectCreate() method, create an object to stack
  * All operations below (except in one case, indicating that the method called) are for the top element of the stack unless called
  * addSetNext() method, remove the top element of the stack and execute the specified method of the top element of the secondary stack
  *
  * addCallMethod(pattern, methodName): call the specified method of the top element of the stack
  * addCallMethod(pattern, methodName, paramCount): Call the specified method of the top element of the stack, which can specify the method
  * Number of parameters addCallMethod(pattern, methodName, paramCount, paramTypes): The top element of the call stack
  * Specify the method, which can specify the number of parameters and type of the method
  *
  * addCallParam(pattern, paramIndex): The default setting specifies the paramIndex parameter as the label content
  * addCallParam(pattern, paramIndex, fromStack): Set the specified paramIndex parameter to the top element of the stack
  * addCallParam(pattern, paramIndex, stackIndex): Set the specified paramIndex parameter to?
  * addCallParam(pattern, paramIndex, attributeName): Set the specified paramIndex parameter as the label attribute
  * value of attributeName addObjectParam(pattern, paramIndex, paramObj): Set the specified paramIndex
  * ParamObj
  *
  * addSetNext(pattern, methodName): Call the methodName method of the element on the top of the stack, generally a method with a parameter.
  * Use the top element of the stack as an argument, such as the add method of list
  *
  */
public class ParseOrder {
    public static void main(String[] args) {
        parseByJavaBean();
    }

    /**
      * Use javaBean for storage
      */
    public static void parseByJavaBean(){
        // 1. Initialize the Digester instance object        Digester digester = new Digester();

        // 2. Parsing the <Order> tag node        // List enters the stack, list object of the top element of the stack        ("Orders", );
        //Order instance is entered into the stack, and the Order instance object is used when the top element of the stack is entered.        ("Orders/Order", );
        //Set the properties of the <Order> tag        ("Orders/Order");

        // 3. Analyze the <goods> tag node        //Goods instance object is stacked        ("Orders/Order/goods", );
        ("Orders/Order/goods");
        //Set other tag contents under <goods>        ("Orders/Order/goods/name");
        ("Orders/Order/goods/price");
        ("Orders/Order/goods/count");
        ("Orders/Order/goods/total_price");
        //Goods object instance is out of the stack        ("Orders/Order/goods", "add");
        //Order object instance is stacked        ("Orders/Order", "add");

        // 4. Load the configuration file        String filePath = "";
        filePath = ("")+"/bin/config/";
        File file = new File(filePath);

        // 5. Analysis        try {
            ArrayList list = (ArrayList) (file);
            (());
        } catch (IOException e) {
            ();
        } catch (SAXException e) {
            ();
        }
    }
}

Running results

[Order [user=Zhang San, date=2008-11-14, price=12279, goodsList=[Goods [id=1, name=IBM notebook, price=8999, count=1, total_price=8999], Goods [id=2, name=Yegor suit, price=1300, count=2, total_price=2600]]]]

4.2 Parsing through Java encoding (list and map storage)

    /**
      * Use list and map for storage (the process is complicated and not recommended)
      */
    public static void parseByMap(){
        Digester digester = new Digester();
        // 1. Define Orders node rules and create a List collection        ("Orders", );

        // 2. Define Orders/Order node rules, create a Map collection to store attributes and content, and place this Map in the List in the previous node        ("Orders/Order", );
        ("Orders/Order", "add");

        // 3. Define the properties of the Orders/Order node        ("Orders/Order", "put", 2);//Calling the put method of the map on the top element of the stack        ("Orders/Order", 0, "name");//Set key        ("Orders/Order", 1, "name");//Set value        ("Orders/Order", "put", 2);
        ("Orders/Order", 0, "date");
        ("Orders/Order", 1, "date");
        ("Orders/Order", "put", 2);
        ("Orders/Order", 0, "price");
        ("Orders/Order", 1, "price");

        // 4. Define a List collection to store the tags under the Orders/Order nodes        ("Orders/Order", "put", 2);
        ("Orders/Order", );
        ("Orders/Order", 0, "goodsList");
        ("Orders/Order", 1, true);

        // 5. Define Orders/Order/goods node rules, store id, name, price, count, total_price attributes or tags respectively        ("Orders/Order/goods", );
        ("Orders/Order/goods", "add");
        ("Orders/Order/goods", "put", 2);
        ("Orders/Order/goods", 0, "id");
        ("Orders/Order/goods", 1, "id");

        ("Orders/Order/goods/name", "put", 2);
        ("Orders/Order/goods/name", 0, "name");
        ("Orders/Order/goods/name", 1);
        ("Orders/Order/goods/price", "put", 2);
        ("Orders/Order/goods/price", 0, "price");
        ("Orders/Order/goods/price", 1);
        ("Orders/Order/goods/count", "put", 2);
        ("Orders/Order/goods/count", 0, "count");
        ("Orders/Order/goods/count", 1);
        ("Orders/Order/goods/total_price", "put", 2);
        ("Orders/Order/goods/total_price", 0, "total_price");
        ("Orders/Order/goods/total_price", 1);

        String filePath = ("")+"/bin/config/";
        (filePath);
        File file = new File(filePath);
        (());
        try {
            ArrayList list = (ArrayList) (file);
            (());
        } catch (IOException e) {
            ();
        } catch (SAXException e) {
            ();
        }
    }

4.3 Parsing through xml configuration

4.3.1 Configuration file

&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;digester-rules&gt;
    &lt;pattern value="Orders"&gt;
        &lt;object-create-rule classname="" /&gt;  
        &lt;!-- Configuration&lt;Order&gt;Label --&gt;
        &lt;pattern value="Order"&gt;
            &lt;object-create-rule classname="" /&gt;
                &lt;set-properties-rule/&gt;

            &lt;!-- Configuration&lt;goods&gt;Label --&gt;
            &lt;pattern value="goods"&gt;
                &lt;object-create-rule classname="" /&gt;
                &lt;set-properties-rule&gt;
                    &lt;alias attr-name="id" prop-name="id" /&gt;&lt;!-- idProperties correspond tojavabeanofid --&gt;
                &lt;/set-properties-rule&gt;
                &lt;bean-property-setter-rule pattern="name" propertyname="name" /&gt;&lt;!-- nameProperties correspond tojavabeanofname --&gt;
                &lt;bean-property-setter-rule pattern="price" propertyname="price" /&gt;&lt;!-- priceLabel对应javabeanofprice --&gt;
                &lt;bean-property-setter-rule pattern="count" propertyname="count" /&gt;&lt;!-- countLabel对应javabeanofcount --&gt;
                &lt;bean-property-setter-rule pattern="total_price" propertyname="total_price" /&gt;&lt;!-- total_priceLabel对应javabeanoftotal_price --&gt;
                &lt;set-next-rule methodname="add" paramtype=""/&gt;

            &lt;/pattern&gt;
            &lt;set-next-rule methodname="add" paramtype=""/&gt;
        &lt;/pattern&gt;
    &lt;/pattern&gt;
&lt;/digester-rules&gt;  

4.3.2 Java parsing

public static void parseByXmlConfig() throws IOException, SAXException, URISyntaxException{
        // 1. Load the rule configuration file        URL rule = ()
                .getContextClassLoader()
                .getResource("config/");

        // 2. Load the configuration file to be parsed        Reader reader = null;
        try {
            reader = new InputStreamReader(
                    new FileInputStream(
                            new File(("") + "/bin/config/")), "utf-8");
        } catch (FileNotFoundException e) {
            ();
        }

        // 3. Create Digester instance object based on the rule configuration file        InputSource in = new InputSource(new InputStreamReader(new FileInputStream(new File(()))));
        Digester digester = (in);

        // 4. Perform parsing and print the results        List list = (List) (reader);
        (());
        try {
            if(reader != null){
                ();
            }
        } catch (Exception e) {
            ();
        }
    }

result

[Order [user=Zhang San, date=2008-11-14, price=12279, goodsList=[Goods [id=1, name=IBM notebook, price=8999, count=1, total_price=8999], Goods [id=2, name=Yegor suit, price=1300, count=2, total_price=2600]]]]

5. Summary

If you need to call the addSetNext() method, the addObjectCreate() method and the addSetNext() method should appear in pairs

First of all, you need to know that the addSetNext() method is a method that calls the secondary stack top element, and generally takes the top element as a parameter. As in the above example, when storing using list and map, the creation order is Orders—>Order—>goods, respectively, and the corresponding list and map are list(Orders)—>map(Order)—>list(goodsList)—>map(goods) respectively. When encountering the Orders/Order node, a map and a list are created respectively to represent the order and product collection. When the < /order> end tag is encountered, the add() method of list(Orders) needs to be called, that is, the top element at this time is map(Order) and the second top element at the top element is list(Orders). If addSetNext() is written after list(goodsList) is created, the top element and the secondary top element at this time are list(goodsList) and map(Order), and map does not have an add method, so an error will be reported:

: No such accessible method: add() on object:

The parsing can be achieved by using Java encoding and configuration rules. In fact, the two look very similar and proficient in one of them, and the other one is self-taught

The above is the detailed content of the three ways to use Digester to parse XML files. For more information about Digester parsing XML files, please pay attention to my other related articles!