【问题标题】:Query on xml file with special case使用特殊情况查询 xml 文件
【发布时间】:2017-03-01 00:04:28
【问题描述】:

我有 2 个从 Stackoverflow 收集的大文件,名为 posts.xmlquestions.txt,结构如下:

posts.xml:

<posts>
  <row Id="4" PostTypeId="1" AcceptedAnswerId="7" CreationDate="2008-07-31T21:42:52.667" Score="322" ViewCount="21888" Body="..."/>
  <row Id="6" PostTypeId="1" AcceptedAnswerId="31" CreationDate="2008-07-31T22:08:08.620" Score="140" ViewCount="10912" Body="..." />
  ...
</posts>

帖子可以是问题或答案(两者)

questions.txt:

Id,CreationDate,CreationDatesk,Score
123,2008-08-01 16:08:52,20080801,48
126,2008-08-01 16:10:30,20080801,33
...

我想只查询一次帖子并使用 lucene 索引选定的行(它们的 ID 在 questions.txt 文件中)。由于 xml 文件非常大(大约 50GB),所以查询和索引的时间对我来说很重要。

现在的问题是:如何在posts.xml 中找到在questions.txt 中重复的所有选定行

这是我迄今为止的做法:

SAXParserDemo.java:

public class SAXParserDemo {
    public static void main(String[] args){

        try {
            File inputFile = new File("D:\\University\\Information Retrieval 2\\Hws\\Hw1\\files\\Posts.xml");
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
            UserHandler userhandler = new UserHandler();
            saxParser.parse(inputFile, userhandler);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Handler.java:

public class Handler extends DefaultHandler {

    public void getQuestiondId() {
        ArrayList<String> qIDs = new ArrayList<String>();
        BufferedReader br = null;
        try {
            String qId;
            br = new BufferedReader(new FileReader("D:\\University\\Information Retrieval 2\\Hws\\Hw1\\files\\Q.txt"));
            while ((qId = br.readLine()) != null) {
                qId = qId.split(",")[0];  //this is question id
                findAndIndexOnPost(qId);    //find this id on posts.xml then index it!
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void findAndIndexOnPost(String qID) {

    }

    @Override
    public void startElement(String uri,
                             String localName, String qName, Attributes attributes)
            throws SAXException {
        if (qName.equalsIgnoreCase("row")) {
            System.out.println(attributes.getValue("Id"));
            switch (attributes.getValue("PostTypeId")) {
                case "1":
                    String id = attributes.getValue("Id");
                    break;
                case "2":
                    break;
                default:
                    break;
            }

        }
    }
}

更新:

我需要在每次迭代中保持 xml 文件的指针。但是对于 SAX,我不知道该怎么做。

【问题讨论】:

    标签: java xml


    【解决方案1】:

    你要做的是:

    • 读取 TXT 文件(可能是一个简单的流就可以了)。
    • 将所有Id 值添加到List&lt;Integer&gt; questionIds - 一个接一个。您必须手动解析它们(使用正则表达式或String.indexOf())。
    • 在您的 Handler 实现中只需比较 questionIds.contains(givenId)
    • 使用简单的 REST 请求 (POST/PUT) 将接收到的对象(来自 XML)发送到 Elastic Search。

    哒哒!您的数据现在已使用 lucene 进行索引。

    另外,更改将数据传递到 SAX 解析器的方式。与其给它一个File,不如为它创建一个InputStream 的实现,你可以给它saxParser.parse(inputStream, userhandler);。在此处获取流中位置的信息:Given a Java InputStream, how can I determine the current offset in the stream?

    【讨论】:

    • 谢谢,我已经做了这样的事情,而且它正在工作!虽然我用HashSet&lt;String&gt;而不是List&lt;Integer&gt;,因为我听说contains方法的顺序是O(1)。是吗?
    猜你喜欢
    • 2021-02-17
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 2016-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多