2

假设我创建了一个对象,以进一步简化使用 DOM 解析器读取 XML 文档的过程。为了“进入”一个节点或元素,我想使用单行从文档的开头到我的目标数据,隐藏在文档中的某个位置,同时绕过 DOM 的额外“绒毛”解析器(例如doc.getElementsByTagName("data").item(0)当“数据”元素内只有一项时)。

为了这个问题,让我们假设没有重复的元素标签,并且我知道我需要导航到哪里才能从文档中获取我需要的数据,其中数据是一个简单的字符串。这个想法是设置简化的阅读器,以便它也可以用于文档中其他位置的其他数据,而不必一直编写新方法。以下是我尝试过的一些示例代码:

public class SimplifiedReader {
    Document doc;
    Element ele;
    public SimplifiedReader(Document doc) {
        this.doc = doc;
        ele = doc.getDocumentElement();
    }

    public SimplifiedReader fromRoot() {
        ele = doc.getDocumentElement();
        return this;
    }

    public SimplifiedReader withEle(String elementName) {
        ele = ele.getElementsByTagName(elementName).item(0);
        return this;
    }

    public String getTheData(String elementName) {
        return ele.getTextContent();
    }
}

示例 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<fileData>
    <subData>
        <targetData>Hello World!</targetData>
        <otherData>FooBar!</otherData>
    </subData>
</fileData>

这使我能够浏览 XML 文件,并检索到String“Hello World!”。和“FooBar!” 使用此代码:

SimplifiedReader sr = new SimplifiedReader(doc);
String hwData = sr.withEle("fileData").withEle("subData").getTheData("targetData");
String fbData = sr.getTheData("otherData");

或者,如果我不得不去另一个线程来获取数据“FooBar!”,我会这样做:

String fbData = sr.fromRoot().withEle("fileData2").withEle("subData2").getTheData("otherData");

有没有更好/更正确的方法来做到这一点?编辑:注意:这个问题更多是关于从它内部的方法返回对象的方法(return this;),以减少为访问存储在树格式中的特定数据而编写的代码量,而不是关于如何读取XML 文件。(我最初认为这是单例模式,直到威廉纠正我……谢谢威廉)。

提前感谢您的帮助。

4

2 回答 2

4
  1. 我在这里看不到任何单例模式的痕迹。它主要类似于Builder模式,但也不是。它只是实现了一个流畅的 API。

  2. 你的方法似乎非常好和实用。

  3. 我可能会建议不要使用fromRoot(),而是每次都构建一个新实例。该实例非常轻量级,因为所有重量级的东西都驻留在Document它包装的实例中。

  4. 你甚至可以一直保持不变,从withEle(). 这为您带来了许多很酷的属性,例如共享对象的自由,每个代码路径都可以自由使用它作为起点来获取与其相关的特定内容,跨线程共享等。底层Document是可变的,但通常当代码完全是关于阅读时,这不会产生现实生活中的问题。

于 2014-07-18T19:19:15.977 回答
3

有没有更好/更正确的方法来做到这一点?

是的,有很多更好的方法可以从 XML 中提取值。

一种是使用 XPath,例如XMLBeam

import java.io.IOException;
import org.xmlbeam.XBProjector;
import org.xmlbeam.annotation.XBDocURL;
import org.xmlbeam.annotation.XBRead;

public class App {

    public static void main(String[] args) throws IOException {
        FileDate fileDate = new XBProjector().io().fromURLAnnotation(FileDate.class);
        System.out.println(fileDate.getTargetDate());
        // Hello World!
        System.out.println(fileDate.getOtherDate());
        // FooBar!
    }

    @XBDocURL("resource://filedate.xml")
    public interface FileDate {

        @XBRead("/fileData/subData/targetData")
        String getTargetDate();

        @XBRead("/fileData/subData/otherData")
        String getOtherDate();
    }
}
于 2014-07-18T19:21:09.977 回答