2

CSV 形式のデータを xml 要素内に配置することの長所と短所は何ですか?

マトリックス データ フィールドを持つ Java のオブジェクトを xml にシリアル化する必要があります。私は、Jaxb でデータ バインディングを使用するという考えを断念しました。コレクションを含むジェネリックとコレクションは、対処するのが面倒です。

マトリックスの単純なスキーマを考えましたが、CSV へのマトリックスのシリアル化も実装する必要があるため、CSV 文字列を要素内のテキスト ノードとしてダンプしないのはなぜですか? また、ファイルが少し小さくなります。

この考えに反対する議論を思いつくことができますか?

この要素に csv mimetype のようなものを追加する必要がありますか?

編集:これが私が選んだ解決策です。Super-CSVを使用しています。ジェネリック型は実行時に消去されるため、列挙型が必要です。メインの xml ファイルは csv ファイルを参照します。

static public enum SerializableType{INTEGER,DOUBLE,...};

@SuppressWarnings("unchecked")
public static <T> Matrix<T> fromCSV(InputStream in, CsvPreference pref, SerializableType t)
{

    Matrix<T> o = new Matrix<T>();
    // Super-csv class
    CsvListReader csv_reader = new CsvListReader(new InputStreamReader(in), pref);

    Integer n = null;
    try {
        List<String> l = csv_reader.read(); 
        n = l.size(); o.n = n;

        int i=0;

        while(l!=null)
        {
            o.appendRow();
            T val;
            for(int j=0;j<n;j++)
            {
                switch(t)
                {
                case INTEGER:
                    val = (T)Integer.valueOf(Integer.parseInt(l.get(j)));
                    break;
                case DOUBLE:
                    val = (T)Double.valueOf(Double.parseDouble(l.get(j)));
                    break;
                case <...>

                default:
                    throw new IllegalArgumentException();
                }
                o.set(i,j, val);
            }
            i++;

            l = csv_reader.read();
        }

        csv_reader.close();

    } catch (IOException e) {

        e.printStackTrace();
    }

    return o;
}


public static<T> void toCSV(Matrix<T> m, CsvListWriter csv_writer, SerializableType t)
{

    try {

        for(int i=0;i<m.rowCount();i++)
        {
            ArrayList<String> l = new ArrayList<String>();

            for(int j=0;j<m.columnCount();j++)
            {
                if(m.get(i,j)==null)
                {
                    l.add(null);
                }
                else{
                    switch(t)
                    {
                    case INTEGER:
                        l.add(Integer.toString((Integer)m.get(i,j)));
                        break;
                    case DOUBLE:
                        l.add(Double.toString((Double)m.get(i,j)));
                        break;
                    case 
                        <...>

                    default:
                        throw new IllegalArgumentException();
                    };
                }
            }

            csv_writer.write(l);
        }

        csv_writer.flush();
        csv_writer.close();
    } catch (IOException e) {

        e.printStackTrace();
    }
}
4

2 に答える 2

1

XML スキーマを使用すると、項目がスペースで区切られたコレクション型を定義できます。

<xs:list itemType="xs:int"/>

以下は、JAXB でこれを活用してマトリックスを表現する方法の完全な例です。

Java モデル (ルート)

out 行列を表すために 2 次元の int 配列を使用します。を使用しXmlAdapterて、デフォルト以外の配列表現を取得します ( JAXB & java.util.Mapを参照) 。

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
public class Root {

    private int[][] matrix;

    @XmlJavaTypeAdapter(MatrixAdapter.class)
    public int[][] getMatrix() {
        return matrix;
    }

    public void setMatrix(int[][] matrix) {
        this.matrix = matrix;
    }

}

XmlAdapter (マトリックス アダプター)

XML 表現で注釈int[]を付けると、スペース区切りのテキストになります。@XmlValue

import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class MatrixAdapter extends XmlAdapter<MatrixAdapter.AdaptedMatrix, int[][]>{

    public static class AdaptedMatrix {
        @XmlElement(name="row")
        public List<AdaptedRow> rows;
    }

    public static class AdaptedRow {

        @XmlValue
        public int[] row;
    }

    @Override
    public AdaptedMatrix marshal(int[][] matrix) throws Exception {
        AdaptedMatrix adaptedMatrix = new AdaptedMatrix();
        adaptedMatrix.rows = new ArrayList<AdaptedRow>(matrix.length);
        for(int[] row : matrix) {
            AdaptedRow adaptedRow = new AdaptedRow();
            adaptedRow.row = row;
            adaptedMatrix.rows.add(adaptedRow);
        }
        return adaptedMatrix;
    }

    @Override
    public int[][] unmarshal(AdaptedMatrix adaptedMatrix) throws Exception {
        List<AdaptedRow> adaptedRows = adaptedMatrix.rows;
        int[][] matrix = new int[adaptedRows.size()][];
        for(int x=0; x<adaptedRows.size(); x++) {
            matrix[x] = adaptedRows.get(x).row;
        }
        return matrix;
    }

}

デモコード

以下は、すべてが機能することを証明するために実行できるデモ コードです。

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum17119708/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

input.xml/出力

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <matrix>
      <row>1 2 3 4</row>
      <row>5 6 7 8</row>
   </matrix>
</root>

input.xml/出力

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <matrix>
        <row>1 2 3</row>
        <row>4 5 6</row>
        <row>7 8 9</row>
    </matrix>
</root>
于 2013-06-17T14:58:55.767 に答える