按行划分XML组信息

时间:2014-07-26 08:01:26

标签: java xml-parsing

我有一个具有这种特殊形式的特定数据库:

<Database  NumTables="5">
    <Table TableName="table_name_0" TableID="0" NumOriginalColumns="8" NumColumns="8" NumRows="5">
        <Column ColumnName="column_name_0" ColumnID="0" ColumnType="Int32">
            <Cell>1</Cell>
            <Cell>2</Cell>
            <Cell>3</Cell>
            <Cell>4</Cell>
            <Cell>5</Cell>
        </Column>
        <Column ColumnName="column_name_1" ColumnID="1" ColumnType="Int16">
            <Cell>5</Cell>
            <Cell>2</Cell>
            <Cell>8</Cell>
            <Cell>32</Cell>
            <Cell>42</Cell>
        </Column>
    ... (other columns)
    </Table>
    ... (other tables)
</Database>

当我想按行分组信息时,我喜欢这样:

Element root = this.document.getRootElement();    
Element table = root.getChildren().get(0);
int numRows = Integer.parseInt(table.getAttributeValue("NumRows"));
for (int currentRow = 0; currentRow < numRows; currentRow++) {
    Integer column_0 = Integer.parseInt(table.getChildren().get(0).getChildren().get(currentRow).getValue());
    Integer column_1 = Integer.parseInt(table.getChildren().get(1).getChildren().get(currentRow).getValue());
    ...
}

它运行良好,但我认为这段代码不是很好,因为我使用了两次非常繁琐的构造getChildren.get(number)。所以我想知道,是否存在使用jdom2执行此操作的正确解决方案。

1 个答案:

答案 0 :(得分:0)

这是第一步:描述XML文件的XML模式,称之为db.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        version="2.0">
<xs:element name="Database" type="Database"/>
<xs:complexType name="Database">
 <xs:sequence>
   <xs:element name="Table" type="Table" maxOccurs="unbounded"/>
 </xs:sequence>
 <xs:attribute name="NumTables"  type="xs:int"/>
</xs:complexType>
<xs:complexType name="Table">
 <xs:sequence>
   <xs:element name="Column" type="Column" maxOccurs="unbounded"/>
 </xs:sequence>
 <xs:attribute name="TableName"          type="xs:string"/>
 <xs:attribute name="TableID"            type="xs:int"/>
 <xs:attribute name="NumOriginalColumns" type="xs:int"/>
 <xs:attribute name="NumColumns"         type="xs:int"/>
 <xs:attribute name="NumRows"            type="xs:int"/>
</xs:complexType>
<xs:complexType name="Column">
 <xs:sequence>
   <xs:element name="Cell" type="xs:string" maxOccurs="unbounded"/>
 </xs:sequence>
 <xs:attribute name="ColumnName" type="xs:string"/>
 <xs:attribute name="ColumnID"   type="xs:int"/>
 <xs:attribute name="ColumnType" type="xs:string"/>
</xs:complexType>
</xs:schema>

如果你跑

$ xjc db.xsd

在子目录generated中生成了几个Java类(当然,这个名称可以改进)。

现在,我们需要一个简单的过程来解组您的XML文件:

public class Main {

private static final String PACKAGE = "generated";
private static final String SCHEMA  = "table.xsd";
private static final String XMLIN   = "database.xml";

private Database db;

void unmarshal() throws Exception {
    JAXBContext jc = JAXBContext.newInstance( PACKAGE );
    Unmarshaller m = jc.createUnmarshaller();

    JAXBElement<Database> jbe = null;
    try {
        StreamSource source =
            new StreamSource( new FileInputStream( XMLIN ) );
        jbe = m.unmarshal( source, Database.class );
        db = jbe.getValue();
    } catch( Exception e  ){
        System.out.println( "EXCEPTION: " + e.getMessage() );
        e.printStackTrace();
}
}

public Database getDatabase(){
    return db;
}

public static void main( String[] args ) {
    Main main = new Main();
    try {
        main.unmarshal();
        Database db = main.getDatabase();
        for( Table table: db.getTable() ){
            for( Column column: table.getColumn() ){
                 for( String cell: column.getCell() ){
                     System.out.print( " " + cell );
                }
            } 
        }       
    } catch( Exception e ){
        System.err.println( "marshal fails: " );
        e.printStackTrace();
    }
}
}