如何解析文件并将输入映射到多个子记录中?

时间:2015-10-14 04:23:30

标签: java

我必须首先谈到我在Java和编程方面的超级菜鸟。

我的问题:
我在解析textfile并将文件数据放入subrecords时遇到问题。在我的情况下,是否将数据放入新的subrecord的关键是基于文件中标记的名称。

以下是我希望parse/split进入subrecords的文件示例。

SHP
数据1
数据2
数据3
项目A
数据B
数据C
项目A
数据B
数据C
SHP

所以基本上当我遇到SHP的第一次出现时,我想创建一个新的SHP类,然后将以下标记(本例中为DATA)映射到新SHP的字段中对象。但是,如果下一个标记是ITEM,那么我需要在SHP中创建一个新的 ITEM对象,然后映射以下 DATA 标记,直到新的ITEM标记为发现...更糟糕的是,我正在解析的文件中SHP标签的数量也可以是多个。

到目前为止,我所做的是将文件的所有内容放入ArrayList,然后我遍历此列表并根据当前“记录”的值,然后创建一个新对象或映射列表中记录的值。 然而,我完全迷失了所有的循环,我需要一些帮助! :)

有没有一种好方法可以做到这一点?
如何从ArrayList轻松获取数据块并根据当前记录的值提取并将其映射到新对象中?

我想如果你想从头创建一个解析器来映射XML文件中的数据并将其放入对象中,那么会出现同样的问题吗?

实例的扩展版本

如果我提供一些真实的例子和真实数据来说明我的问题,也许会更容易。最初我只是认为它会让人更难理解,但希望这会更容易。

文件和内容: Example file

所以我到目前为止所做的是创建一些应该代表文件中数据的类。我甚至命名类的字段/变量,以便我更容易映射。

以下是课程:

 public class REQUEST {
    public SHIPMENT[] SHIPMENTS;
}
public class SHIPMENT {
    public String IVNO;
    public String CNNAME;
    public String CNADDRESS1;   
    public String CNPC;
    public String CNCITY;

    public PACKAGE[] PACKAGES;
    public ITEM[] ITEMS;    
}

public class PACKAGE {    
    public String GOODSLINE;
    public String GOODSDESCR;
    public String GRWEIGHT;
}

public class ITEM {
    public String ITEMLINE;
    public String ARTNO;
    public String GRWEIGHT;
}

以下是我所做的不能正常工作的代码。我设法创建多个SHIPMENT并创建ITEM,但由于某种原因,数据未映射。我也在调用mapMethod之前将文件的全部内容放入ArrayList中。 ArrayList中每个记录一个fiel行。

好的,所以这就是它的总和,请温柔地对待我:)。

public REQUEST mapRequest(ArrayList<String> inputfile)
        throws IllegalArgumentException, IllegalAccessException {
    REQUEST request = new REQUEST();
    ArrayList<SHIPMENT> shipments = new ArrayList<>();

for (int i = 0; i < inputfile.size(); i++) {

    String recordIdentifier = getRecordIdentifier(inputfile.get(i));
    if (StringUtils.equals(recordIdentifier, "IVNO")) {
        SHIPMENT shipment = new SHIPMENT();
        ArrayList<ITEM> items = new ArrayList<>();

        int j = 0;
        for (j = i; j < inputfile.size(); j++) {

            String currShpRecIdentifier = getRecordIdentifier(inputfile.get(j));
            String nextShpRecIdentifier = StringUtils.EMPTY;
            if (j + 1 < inputfile.size()) {
                nextShpRecIdentifier = getRecordIdentifier(inputfile.get(j + 1));
            }

            try {
                Field field = shipment.getClass().getField(currShpRecIdentifier);
                String shipmentRecordValue = getRecordValue(inputfile.get(j));
                field.set(shipment, shipmentRecordValue);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }

            if (StringUtils.equals(nextShpRecIdentifier, "ITEMLINE")) {
                ITEM item = new ITEM();

                int k = 0;
                for (k = j; k < inputfile.size(); k++) {

                    String currItemRecIdentifier = getRecordIdentifier(inputfile.get(k));
                    String nextItemRecIdentifier = StringUtils.EMPTY;
                    if (k + 1 < inputfile.size()) {
                        nextItemRecIdentifier = getRecordIdentifier(inputfile
                                .get(k + 1));
                    }

                    try {
                        Field field = item.getClass().getField(currItemRecIdentifier);
                        String itemRecordValue = getRecordValue(inputfile.get(k));
                        field.set(item, itemRecordValue);
                    } catch (NoSuchFieldException e) {
                        e.printStackTrace();
                    } catch (SecurityException e) {
                        e.printStackTrace();
                    }

                    if (StringUtils.equals(nextItemRecIdentifier, "ITEMLINE")) {
                        break;
                    }

                }

                items.add(item);
                j = k;
            }

            if (StringUtils.equals(nextShpRecIdentifier, "IVNO")) {
                break;
            }
        }

        shipment.ITEMS = items.toArray(new ITEM[items.size()]);
        shipments.add(shipment);

        i = j;

    }

}

request.SHIPMENTS = shipments.toArray(new SHIPMENT[shipments.size()]);

return request;

}

private String getRecordIdentifier(String in) {
    return StringUtils.left(in, 15).trim();
}

private String getRecordValue(String in) {
    return StringUtils.substring(in, 16).trim();
}

1 个答案:

答案 0 :(得分:0)

我真的没遇到你遇到麻烦的地方。

FileReader input = new FileReader(filePathToYourFile);
BufferedReader bufRead = new BufferedReader(input);
String readLine = null;
String shp = "SHP"; //or define them as "constants" with static final
String item = "ITEM";
String data = "DATA";
ArrayList<SHPType> listOfSHPObjects = new ArrayList<SHPType>();
SHPType lastSHP;
ItemType lastItem;

while ( (readLine = bufRead.readLine()) != null)
{    
    String[] splittedLine = readLine.split(" ");
    if(splittedLine[0].equals(shp))
    { //if it's an SHP, make an SHP object, and add it to a list.
        lastSHP = new SHPType();
        listOfSHPObjects.add(lastshp);
    }
    if(splittedLine[0].equals(data) && lastSHP != null)
    { //if it's a data object, either add it to the property/field/list/collection of the latest SHP, or if you have found an item, add it to the item.
      //of course if you haven't found any SHP objects, discard it, as it doesn't belong anywhere
        if(lastItem == null)
           lastSHP.CollectionThatHoldsData.add(new DataType());
        else
           lastItem.CollectionThatHoldsData.add(new DataType());
    }
    if(splittedLine[0].equals(item) && lastSHP != null)
    {
        //create a new last item and add it to the item list of the last SHP found. New data will be added to this item
        lastItem = new ItemType();
        lastSHP.CollectionThatHoldsItems.add(lastItem);
    }
}
//close the file etc...

这假设您找到以下内容:

数据 项目 SHP 等等 第一个DATA和ITEM毫无意义。如果要将它们分配给您找到的第一个SHP,请将它们存储在waitingForSHP arrayList中,并在找到第一个SHP后立即将它们添加到那里。

此外,如果要根据第二个值(数据5中的fe,表示5)创建SHP /项目/数据,请将5(我的示例中为splittedLine [1]变量)作为参数传递给构造函数SHPType / ItemType / DataType对象的。它将是一个字符串,因此如果您想将其作为整数传递,则必须将其转换(Integer.parseInt(splittedLine [1]))。