0

我需要解析一个大型 XML 文件(可能会在 Java 中使用 StAX)并将其输出到一个分隔的文本文件中,并且我有几个设计问题。首先是 XML 的示例

    <demographic>
        <value>001</value>
        <question>Name?</question>
        <value>Bob</value>
        <question>Last Name?</question>
        <value>Smith</value>
        <followUpQuestions>
            <question>Middle Init.</question>
            <value>J</value>
        </followUpQuestions>
    </demographic>

这需要输出(在分隔的输出文件中)为

001~Bob~Smith~J

所以这是我的问题:

  1. 我如何区分所有不同的“值”标签,因为标签名称不是唯一的。目前,我试图通过让“状态”变量在传递诸如“名称?”之类的问题文本后打开来解决此问题,但是这种方法对于第一个值并不真正适用,因为我必须检查以确保“名称”并且“姓氏”状态已关闭,以确保我获得第一个值。

  2. 每次客户更改问题的文本(发生这种情况)时,我都必须更改代码并重新编译它。有没有办法避免这种情况?也许将问题文本保存在程序读取的文本文件中?

  3. 这可以扩展吗?我需要提取 100 多个值,并且 XML 文件通常大约 2 gigs 大。

提前感谢您的帮助(来自 Java 和 XML 新手)!

更新:这是我尝试编写解决方案的代码,有人可以帮忙简化吗?必须有一种不那么混乱的方法来做到这一点:

import javax.xml.stream.XMLInputFactory; 
import javax.xml.stream.XMLStreamConstants; 
import javax.xml.stream.XMLStreamException; 
import javax.xml.stream.XMLStreamReader;
import java.io.*;
class TestJavaForStackOverflow{

boolean nameState = false,
                lastNameState = false,
                middleInitState = false;

String  name = "",
                lastName = "",
                middleInit = "",
                value = "";

public void parse() throws IOException, XMLStreamException{
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader streamReader = factory.createXMLStreamReader(
                new FileReader("/n04/data/revmgmt/anthony/scripts/Java_Programs/TestJavaForStackOverflow.xml"));



        while(streamReader.hasNext()){
                streamReader.next();

                if(streamReader.getEventType() == XMLStreamReader.START_ELEMENT){
                        if("demographic".equals(streamReader.getLocalName())){
                                parseDemographicInformation(streamReader);
                        } 
                }
        }
        System.out.println(value + "~" + name + "~" + lastName + "~" + middleInit);
}

public void parseDemographicInformation(XMLStreamReader streamReader) throws XMLStreamException {
        while(streamReader.hasNext()){
                streamReader.next();

                if(streamReader.getEventType() == XMLStreamReader.END_ELEMENT){
                        if("demographic".equals(streamReader.getLocalName())){
                            return;
                        }
                } 
                else if(streamReader.getEventType() == XMLStreamReader.START_ELEMENT){
                     if("question".equals(streamReader.getLocalName())){
                        streamReader.next();
                        if("Name?".equals(streamReader.getText())){
                            nameState = true;
                        }
                        else if("Last Name?".equals(streamReader.getText())){
                            lastNameState = true;
                        }
                        else if("Middle Init.".equals(streamReader.getText())){
                            middleInitState = true;
                        }
                    }
                    else if("value".equals(streamReader.getLocalName())){
                        streamReader.next();
                        if(nameState){ 
                            name = streamReader.getText();
                            nameState = false;
                        }
                        else if (lastNameState){
                            lastName = streamReader.getText();
                            lastNameState = false;
                        }
                        else if (middleInitState){ 
                            middleInit = streamReader.getText();
                            middleInitState = false;
                        }
                        else {
                            value = streamReader.getText();
                        }
                    }
                }

        }
}
public static void main(String[] args){
    TestJavaForStackOverflow t = new TestJavaForStackOverflow();
    try{t.parse();}
    catch(IOException e1){}
    catch(XMLStreamException e2){}
}
}
4

1 回答 1

0

我认为如果你有很多不同的问题要解析,标志的可扩展性不是很好,而且保存结果的全局变量也不是......如果你有 100 个问题,那么你需要 100 个变量,当它们改变时是时候让他们保持最新状态了。我会使用一个映射结构来保存结果,另一个来保存每个问题文本与您尝试捕获的相应字段之间的对应关系(这不是实际的 Java,只是一个近似值):

公共地图解析人口统计信息(XmlStream xml,地图问题地图){
  地图记录 = new Map();
  字符串字段 = "id";
  而((elem = xml.getNextElement())) {
    if(elem.tagName == "问题") {
      字段 = questionMap[elem.value];
    } else if(elem.tagName == "value") {
      记录[字段] = elem.value;
    }
  }
  退货记录;
}

然后你有这样的东西来输出结果:

String[] fieldsToOutput = { "id", "firstName", "lastName" }; // 理想情况下,也可以从文件中读取它,以便可以动态更改它

// ...

for(int i=0; i < fieldsToOutput.length; i++){
  如果(我> 0)
    System.out.print("~");
  System.out.print(record[fieldsToOutput[i]]);
}
System.out.println();
于 2013-10-16T01:28:51.307 回答