DocumentBuilderFactory解析xml

本文介绍了如何利用Java中的DocumentBuilderFactory来解析XML文件。通过调用newDocumentBuilder()创建DocumentBuilder实例,然后使用parse()方法读取XML文件,返回一个Document对象。在解析过程中需要注意捕获IO和SAX异常。Document对象提供了访问XML节点标签名、属性、子节点等信息的方法,适合构建通用的XML节点处理逻辑。完整代码已上传至GitHub。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用DocumentBuilderFactory来解析xml文件

首先是主函数代码:

    public static void main(String[] args) {
        try {
            final Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(Main.class.getResourceAsStream("/actions.xml"));

            Reader reader = new Reader();
            reader.load(new Entry(xml.getDocumentElement()));

        } catch (final IOException e) {

        } catch (final SAXException e) {

        }catch (final ParserConfigurationException e) {

        }
    }

这里使用了DocumentBuilderFactory::newInstance()获取了一个DocumentBuilderFactory实例。

然后调用DocumentBuilderFactory::newDocumentBuilder()官方文档的描述如下:

Creates a new instance of a DocumentBuilder using the currently configured parameters.

然后使用DocumentBuilder::parse(String uri) parse一个xml文件,结果是返回一个Document实例,同时这个方法需要捕捉IO和SAX异常,

其中的SAXException时parse发生错误时会抛出的错误。


在进行xml的解析之前,我们先来看看Document的定义

Interface Document extends node

因此包括node的方法我们都是可以使用的,那么实际在解析一个xml文件的时候,我们经常需要进行的操作大致为一下几种,

1.获取当前node的tagname

2.获取当前node的attributes

3.选中当前node下的特定child node

4.获取当前node下的child List<node>


所以我们可以定义一个类来给所有的node添加这种通用的特性

    static class Entry {

        private Element element;

        private Map<String, String> attributes;

        private List<Entry> children;

        private Map<String, List<Entry> > selected = new HashMap<String, List<Entry> >();

        public Entry(final Element element) {
            this.element = element;
        }

        public String getName() {
            return this.element.getTagName();
        }

        public Map<String, String> getAttributes() {
            if(this.attributes != null) {
                return this.attributes;
            }

            this.attributes = new LinkedHashMap<String, String >();
            final NamedNodeMap attrs = this.element.getAttributes();

            for(int i = 0; i < attrs.getLength(); ++i ) {
                final Attr attr = (Attr)attrs.item(i);
                this.attributes.put(attr.getName(), attr.getValue());
            }

            return this.attributes;
        }

        public String getAttribute(final String attributeName) {
            final Attr attribute = this.element.getAttributeNode(attributeName);

            if (attribute == null) {
                return null;
            }

            return attribute.getValue();
        }

        public List<Entry> selectChildren(final String tagName) {

            List<Entry> children = this.selected.get(tagName);
            if ( children!=null ) {
                return children;
            }
            children = new ArrayList<Entry>();
            for( final Entry child : getChildren() ) {
                if ( child.getName().equals(tagName)) {
                    children.add(child);
                }
            }

            this.selected.put(tagName, children);

            return children;
        }

        public List<Entry> getChildren() {

            if ( this.children!=null) {
                return this.children;
            }

            this.children = new ArrayList<Entry>();
            final NodeList childNodes = this.element.getChildNodes();
            for( int i = 0; i<childNodes.getLength(); ++i) {
                final Node childNode = childNodes.item(i);
                if ( childNode instanceof Element ) {
                    this.children.add(new Entry((Element)childNode));
                }
            }

            return this.children;
        }
    }

这里我使用的时shimeji里面实现Entry类,然后我们创建一个Reader类来试着读取某个xml的参数

    static class Reader {

        private final Map<String, String> constants = new LinkedHashMap<String, String>();

        public void load(final Entry configurationNode) throws IOException {


            for (final Entry constant : configurationNode.selectChildren("定数")) {
                System.out.println("constant is: " + constant.getAttribute("値"));

                constants.put( constant.getAttribute("名前"), constant.getAttribute("値") );
            }

            for (final Entry list : configurationNode.selectChildren("動作リスト")) {

                for (final Entry node : list.selectChildren("動作")) {
                    System.out.println("node name is: " + node.getName());
                }
            }

            for (final Entry list : configurationNode.selectChildren("行動リスト")) {
                System.out.println("list name is: " + list.getName());
                loadBehaviors(list, new ArrayList<String>());
            }
        }

        private void loadBehaviors(final Entry list, final List<String> conditions) {
            for (final Entry node : list.getChildren()) {

                if (node.getName().equals("条件")) {

                    final List<String> newConditions = new ArrayList<String>(conditions);
                    newConditions.add(node.getAttribute("条件"));

                    loadBehaviors(node, newConditions);

                } else if (node.getName().equals("行動")) {
                    System.out.println("action is: " + node.getName());
                }
            }
        }
    }

下面附上运行结果


这段代码已经上传到:

https://github.com/AlanJager/java_learning




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值