Using_Digester_2

本文介绍如何使用Apache Commons Digester库解析XML文档。通过指定模式和规则,Digester可以将XML转换为Java对象。文章提供了配置示例,展示了如何创建对象、设置属性以及调用方法。

 

Specifying Patterns and Rules

The Digester class processes the input XML document based on patterns and rules. The patterns must match XML elements, based on their name and location in the document tree. The syntax used to describe the matching patterns resembles the XPath match patterns, a little: the pattern catalog matches the top-level <catalog> element, the pattern catalog/book matches a <book> element nested directly inside a <catalog> element, but nowhere else in the document, etc.

 

 

All patterns are absolute: the entire path from the root element on down has to be specified. The only exception are patterns containing the wildcard operator *: the pattern */name will match a <name> element anywhere in the document. Also note that there is no need for a special designation for the root element, since all paths are absolute.

 

 Whenever the Digester encounters one of the specified patterns, it performs the actions that have been associated with it. In this, the Digester framework is of course related to a SAX parser (and in fact, the Digester class implements org.xml.sax.ContentHandler and maintains the parse stack). All rules to be used with the Digester must extend org.apache.commons.digester.Rule -- which in itself exposes methods similar to the SAX ContentHandler callbacks: begin() and end() are called when the opening and closing tags of the matched element are encountered.

The body() method is called for the content nested inside of the matched element, and finally, there is a finish() method, which is called once processing of the closing tag is complete, to provide a hook to do possible final clean-up chores. Most application developers will not have to concern themselves with these functions, however, since the standard rules that ship with the framework are likely to provide all desired functionality.

To unmarshal a document, then, create an instance of the org.apache.commons.digester.Digester class, configure it if necessary, specify the required patterns and rules, and finally, pass a reference to the XML file to the parse() method. This is demonstrated in the DigesterDriver class below. (The filename of the input XML document must be specified on the command line.)

import org.apache.commons.digester.*;

import java.io.*;
import java.util.*;

public class DigesterDriver {

   public static void main( String[] args ) {

      try {
         Digester digester = new Digester();
         digester.setValidating( false );

         digester.addObjectCreate( "catalog", Catalog.class );

         digester.addObjectCreate( "catalog/book", Book.class );
         digester.addBeanPropertySetter( "catalog/book/author", "author" );
         digester.addBeanPropertySetter( "catalog/book/title", "title" );
         digester.addSetNext( "catalog/book", "addBook" );

         digester.addObjectCreate( "catalog/magazine", Magazine.class );
         digester.addBeanPropertySetter( "catalog/magazine/name", "name" );

         digester.addObjectCreate( "catalog/magazine/article", Article.class );
         digester.addSetProperties( "catalog/magazine/article", "page", "page" );
         digester.addBeanPropertySetter( "catalog/magazine/article/headline" );
         digester.addSetNext( "catalog/magazine/article", "addArticle" );

         digester.addSetNext( "catalog/magazine", "addMagazine" );

         File input = new File( args[0] );
         Catalog c = (Catalog)digester.parse( input );

         System.out.println( c.toString() );

      } catch( Exception exc ) {
         exc.printStackTrace();
      }
   }
}

After instantiating the Digester, we specify that it should not validate the XML document against a DTD -- because we did not define one for our simple Catalog document. Then we specify the patterns and the associated rules: the ObjectCreateRule creates an instance of the specified class and pushes it onto the parse stack. The SetPropertiesRule sets a bean property to the value of an XML attribute of the current element -- the first argument to the rule is the name of the attribute, the second, the name of the property.

Whereas SetPropertiesRule takes the value from an attribute, BeanPropertySetterRule takes the value from the raw character data nested inside of the current element. It is not necessary to specify the name of the property to set when using BeanPropertySetterRule: it defaults to the name of the current XML element. In the example above, this default is being used in the rule definition matching the catalog/magazine/article/headline pattern. Finally, the SetNextRule pops the object on top of the parse stack and passes it to the named method on the object below it -- it is commonly used to insert a finished bean into its parent.

Note that it is possible to register several rules for the same pattern. If this occurs, the rules are executed in the order in which they are added to the Digester -- for instance, to deal with the <article> element, found at catalog/magazine/article, we first create the appropriate article bean, then set the page property, and finally pop the completed article bean and insert it into its magazine parent.

Invoking Arbitrary Functions

It is not only possible to set bean properties, but to invoke arbitrary methods on objects in the stack. This is accomplished using the CallMethodRule to specify the method name and, optionally, the number and type of arguments passed to it. Subsequent specifications of the CallParamRule define the parameter values to be passed to the invoked functions. The values can be taken either from named attributes of the current XML element, or from the raw character data contained by the current element. For instance, rather than using the BeanPropertySetterRule in the DigesterDriver implementation above, we could have achieved the same effect by calling the property setter explicitly, and passing the data as parameter:

   digester.addCallMethod( "catalog/book/author", "setAuthor", 1 );
   digester.addCallParam( "catalog/book/author", 0 );

The first line gives the name of the method to call (setAuthor()), and the expected number of parameters (1). The second line says to take the value of the function parameter from the character data contained in the <author> element and pass it as first element in the array of arguments (i.e., the array element with index 0). Had we also specified an attribute name (e.g., digester.addCallParam( "catalog/book/author", 0, "author" );), the value would have been taken from the respective attribute of the current element instead.

One important caveat: confusingly, digester.addCallMethod( "pattern", "methodName", 0 ); does not specify a call to a method taking no arguments -- instead, it specifies a call to a method taking one argument, the value of which is taken from the character data of the current XML element! We therefore have yet another way to implement a replacement for BeanPropertySetterRule:

   digester.addCallMethod( "catalog/book/author", "setAuthor", 0 );

To call a method that truly takes no parameters, use digester.addCallMethod( "pattern", "methodName" );.

Using CATALINA_BASE: "C:\Users\hw\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\b47a5540-753d-496f-a7ac-2be863a0d0e1" Using CATALINA_HOME: "E:\java_dev\apache-tomcat-9.0.22" Using CATALINA_TMPDIR: "E:\java_dev\apache-tomcat-9.0.22\temp" Using JRE_HOME: "C:\Program Files\Java\jdk1.8.0_361" Using CLASSPATH: "E:\java_dev\apache-tomcat-9.0.22\bin\bootstrap.jar;E:\java_dev\apache-tomcat-9.0.22\bin\tomcat-juli.jar" 16-Jun-2025 19:58:07.775 璀﹀憡 [main] org.apache.tomcat.util.digester.Digester.endElement No rules found matching [Server/Service/Engine/Host/Contex] 16-Jun-2025 19:58:07.778 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.鏈嶅姟鍣ㄧ増鏈�: Apache Tomcat/9.0.22 16-Jun-2025 19:58:07.778 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.鏋勫缓: Jul 4 2019 14:20:06 UTC 16-Jun-2025 19:58:07.778 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.22.0 16-Jun-2025 19:58:07.778 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Windows 11 16-Jun-2025 19:58:07.778 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log OS.鐗堟湰: 10.0 16-Jun-2025 19:58:07.778 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log 缁�.閫�: amd64 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Java 鐜鍙橀噺: C:\Program Files\Java\jdk1.8.0_361\jre 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM 鐗堟湰: 1.8.0_361-b09 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.渚涘簲鍟�: Oracle Corporation 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: C:\Users\hw\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\b47a5540-753d-496f-a7ac-2be863a0d0e1 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: E:\java_dev\apache-tomcat-9.0.22 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=C:\Users\hw\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\b47a5540-753d-496f-a7ac-2be863a0d0e1\conf\logging.properties 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote= 16-Jun-2025 19:58:07.779 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.port=1099 16-Jun-2025 19:58:07.780 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.ssl=false 16-Jun-2025 19:58:07.780 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.password.file=C:\Users\hw\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\b47a5540-753d-496f-a7ac-2be863a0d0e1\jmxremote.password 16-Jun-2025 19:58:07.780 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.access.file=C:\Users\hw\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\b47a5540-753d-496f-a7ac-2be863a0d0e1\jmxremote.access 16-Jun-2025 19:58:07.780 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.rmi.server.hostname=127.0.0.1 16-Jun-2025 19:58:07.780 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048 16-Jun-2025 19:58:07.780 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 16-Jun-2025 19:58:07.780 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs= 16-Jun-2025 19:58:07.782 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=C:\Users\hw\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\b47a5540-753d-496f-a7ac-2be863a0d0e1 16-Jun-2025 19:58:07.782 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=E:\java_dev\apache-tomcat-9.0.22 16-Jun-2025 19:58:07.782 淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=E:\java_dev\apache-tomcat-9.0.22\temp 16-Jun-2025 19:58:07.782 淇℃伅 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_361\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Java\jdk1.8.0_361\jre\bin;D:\hw\python3.8.5;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Windows\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;E:\java_dev\Maven\apache-maven-3.6.1\bin;E:\java_dev\MYSQL\Program Files\MySQL\MySQL Server 8.0\bin;E:\java_dev\node-v16.20.2-win-x64;C:\Program Files\Java\jdk1.8.0_361\bin;E:\java_dev\apache-tomcat-9.0.22\bin;E:\java_dev\apache-tomcat-9.0.22\lib;D:\hw\python3.8.5;D:\hw\pycharm\P鐗坧ycharm\PyCharm 2024.1.3\bin;;D:\hw\pycharm\PyCharm Community Edition 2023.2.3\bin;;C:\Users\hw\AppData\Local\Microsoft\WindowsApps;D:\JAVA\鐜閰嶇疆\IntelliJ IDEA Community Edition 2024.1\bin;;D:\JAVA\鐜閰嶇疆\IntelliJ IDEA 2023.3.4\bin;;D:\Visual Studio Code\Microsoft VS Code\bin;D:\nodejs;;C:\Users\hw\.lmstudio\bin;.] 16-Jun-2025 19:58:07.971 淇℃伅 [main] org.apache.coyote.AbstractProtocol.init 鍒濆鍖栧崗璁鐞嗗櫒 ["http-nio-8080"] 16-Jun-2025 19:58:07.990 淇℃伅 [main] org.apache.coyote.AbstractProtocol.init 鍒濆鍖栧崗璁鐞嗗櫒 ["ajp-nio-8009"] 16-Jun-2025 19:58:07.993 淇℃伅 [main] org.apache.catalina.startup.Catalina.load 鏈嶅姟鍣ㄥ湪[368]姣鍐呭垵濮嬪寲 16-Jun-2025 19:58:08.021 淇℃伅 [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina] 16-Jun-2025 19:58:08.021 淇℃伅 [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.22] 16-Jun-2025 19:58:08.029 淇℃伅 [main] org.apache.coyote.AbstractProtocol.start 寮�濮嬪崗璁鐞嗗彞鏌刐"http-nio-8080"] 16-Jun-2025 19:58:08.035 淇℃伅 [main] org.apache.coyote.AbstractProtocol.start 寮�濮嬪崗璁鐞嗗彞鏌刐"ajp-nio-8009"] 16-Jun-2025 19:58:08.036 淇℃伅 [main] org.apache.catalina.startup.Catalina.start Server startup in [43] milliseconds Connected to server 16-Jun-2025 19:58:18.043 淇℃伅 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory 鎶妛eb 搴旂敤绋嬪簭閮ㄧ讲鍒扮洰褰� [E:\java_dev\apache-tomcat-9.0.22\webapps\manager] 16-Jun-2025 19:58:18.314 淇℃伅 [Catalina-utility-2] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [E:\java_dev\apache-tomcat-9.0.22\webapps\manager] has finished in [271] ms E:\java_dev\apache-tomcat-9.0.22\bin\catalina.bat stop Using CATALINA_BASE: "C:\Users\hw\AppData\Local\JetBrains\IntelliJIdea2024.1\tomcat\b47a5540-753d-496f-a7ac-2be863a0d0e1" Using CATALINA_HOME: "E:\java_dev\apache-tomcat-9.0.22" Using CATALINA_TMPDIR: "E:\java_dev\apache-tomcat-9.0.22\temp" Using JRE_HOME: "C:\Program Files\Java\jdk1.8.0_361" Using CLASSPATH: "E:\java_dev\apache-tomcat-9.0.22\bin\bootstrap.jar;E:\java_dev\apache-tomcat-9.0.22\bin\tomcat-juli.jar" 16-Jun-2025 20:02:31.227 淇℃伅 [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance. 16-Jun-2025 20:02:31.227 淇℃伅 [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-8080"] 16-Jun-2025 20:02:31.322 淇℃伅 [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-8009"] 16-Jun-2025 20:02:31.409 淇℃伅 [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina] 16-Jun-2025 20:02:31.418 淇℃伅 [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-8080"] 16-Jun-2025 20:02:31.418 淇℃伅 [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-8009"] 16-Jun-2025 20:02:31.419 淇℃伅 [main] org.apache.coyote.AbstractProtocol.destroy 姝e湪鎽ф瘉鍗忚澶勭悊鍣� ["http-nio-8080"] 16-Jun-2025 20:02:31.420 淇℃伅 [main] org.apache.coyote.AbstractProtocol.destroy 姝e湪鎽ф瘉鍗忚澶勭悊鍣� ["ajp-nio-8009"] Disconnected from server
06-17
【事件触发一致性】研究多智能体网络如何通过分布式事件驱动控制实现有限时间内的共识(Matlab代码实现)内容概要:本文围绕多智能体网络中的事件触发一致性问题,研究如何通过分布式事件驱动控制实现有限时间内的共识,并提供了相应的Matlab代码实现方案。文中探讨了事件触发机制在降低通信负担、提升系统效率方面的优势,重点分析了多智能体系统在有限时间收敛的一致性控制策略,涉及系统模型构建、触发条件设计、稳定性与收敛性分析等核心技术环节。此外,文档还展示了该技术在航空航天、电力系统、机器人协同、无人机编队等多个前沿领域的潜在应用,体现了其跨学科的研究价值和工程实用性。; 适合人群:具备一定控制理论基础和Matlab编程能力的研究生、科研人员及从事自动化、智能系统、多智能体协同控制等相关领域的工程技术人员。; 使用场景及目标:①用于理解和实现多智能体系统在有限时间内达成一致的分布式控制方法;②为事件触发控制、分布式优化、协同控制等课题提供算法设计与仿真验证的技术参考;③支撑科研项目开发、学术论文复现及工程原型系统搭建; 阅读建议:建议结合文中提供的Matlab代码进行实践操作,重点关注事件触发条件的设计逻辑与系统收敛性证明之间的关系,同时可延伸至其他应用场景进行二次开发与性能优化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值