Как легко сериализовать XML-файл в объектах с помощью библиотеки XStream - PullRequest
1 голос
/ 04 августа 2010

У меня есть следующий XML-файл:

    <?xml version="1.0" encoding="UTF-8"?>
<!--

    This is a sample netbeans project file for a Squawk project.
    You may edit it freely, it doesn't affect the ant-powered build.

 -->
<project xmlns="http://www.netbeans.org/ns/project/1">
    <type>org.netbeans.modules.ant.freeform</type>
    <configuration>
        <general-data xmlns="http://www.netbeans.org/ns/freeform-project/1">
            <properties>
                <property-file>${user.home}/.sunspot.properties</property-file>
                <property-file>build.properties</property-file>
                <property-file>${sunspot.home}/default.properties</property-file>
            </properties>
            <name>${application.title}</name>
            <folders>
                <source-folder>
                    <label>src</label>
                    <type>java</type>
                    <location>src</location>
                </source-folder>
            </folders>
            <ide-actions>
                <action name="build">
                    <target>jar-app</target>
                </action>
                <action name="run">
                    <target>deploy</target>
                    <target>run</target>
                </action>
                <action name="clean">
                    <target>clean</target>
                </action>
                <action name="rebuild">
                    <target>clean</target>
                    <target>jar-app</target>
                </action>
                <action name="javadoc">
                    <target>javadoc</target>
                </action>
            </ide-actions>
            <export>
                <type>folder</type>
                <location>build</location>
                <build-target>jar-app</build-target>
            </export>
            <view>
                <items>
                    <source-folder style="packages">
                        <label>src</label>
                        <location>src</location>
                    </source-folder>
                    <source-file>
                        <location>build.xml</location>
                    </source-file>
                </items>
                <context-menu>
                    <ide-action name="build"/>
                    <ide-action name="rebuild"/>
                    <ide-action name="clean"/>
                    <ide-action name="javadoc"/>
                    <ide-action name="run"/>
                    <action>
                        <label>Build Project + Deploy to Sun SPOT</label>
                        <target>deploy</target>
                    </action>
                    <action>
                        <label>Deploy to Sun SPOT</label>
                        <target>jar-deploy</target>
                    </action>
                    <separator/>
                </context-menu>
            </view>
            <subprojects/>
        </general-data>
        <java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1">
            <compilation-unit>
                <package-root>src</package-root>
                <classpath mode="boot">${sunspot.bootclasspath}</classpath>
                <classpath mode="compile">${sunspot.classpath}</classpath>
                <built-to>build</built-to>
                <source-level>1.4</source-level>
            </compilation-unit>
        </java-data>
        <preferences xmlns="http://www.netbeans.org/ns/auxiliary-configuration-preferences/1">
            <module name="org-netbeans-modules-editor-indent">
                <node name="CodeStyle">
                    <property name="usedProfile" value="default"/>
                    <node name="project">
                        <property name="tab-size" value="8"/>
                        <property name="text-limit-width" value="80"/>
                    </node>
                </node>
                <node name="text">
                    <node name="x-java">
                        <node name="CodeStyle">
                            <node name="project"/>
                        </node>
                    </node>
                </node>
            </module>
        </preferences>
    </configuration>
</project>

Я хочу проанализировать его с помощью java и библиотеки Xstream (сериализовать), чтобы изменить значения некоторых свойств и узлов, а затем десерилизовать его в файле. Но мне трудно и не очень удобно делать классы java для обрабатывать все эти узлы (я должен сделать Java-класс для каждого узла, например: 1 класс для затем 1 класс для и т.д. ...). Я нашел это немного пустой тратой времени. Есть ли другой способ сделать это быстрее с меньше кода. Или, может быть, я понял что-то неправильно в том, как работает библиотека? Спасибо

Ответы [ 2 ]

0 голосов
/ 04 августа 2010

Не уверен, насколько вы привязаны к XStream, но MOXy JAXB предлагает тип отображения, который вы ищете.Ниже приведена частичная выборка того, как ваш объект может быть отображен:

package-info.java (для установки аннотаций на уровне пакета)

Префиксы пространства имен, назначенные здесь, будутиспользуется позже.

@XmlSchema( 
    namespace = "http://www.netbeans.org/ns/project/1", 
    xmlns = {
            @javax.xml.bind.annotation.XmlNs(prefix = "f", namespaceURI = "http://www.netbeans.org/ns/freeform-project/1"),
        },
    elementFormDefault = XmlNsForm.QUALIFIED)
@XmlAccessorType(XmlAccessType.FIELD)
package example; 

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

Project.java

Обратите внимание на использование @XmlPath для разрыва зависимости 1-к-1 между классами и узлами.

package example;

import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
@XmlType(propOrder={"type", "propertyFile", "name"})
public class Project {

    private String type;

    @XmlPath("configuration/f:general-data/f:properties/f:property-file/text()")
    private List<String> propertyFile;

    @XmlPath("configuration/f:general-data/f:name/text()")
    private String name;

    @XmlPath("configuration/f:general-data/f:folders/f:source-folder")
    private List<Folder> sourceFolder;

    @XmlPath("configuration/f:general-data/f:ide-actions/f:action")
    private List<Action> action;

}

Folder.java

package example;

import javax.xml.bind.annotation.XmlType;

@XmlType(namespace="http://www.netbeans.org/ns/freeform-project/1")
public class Folder {

    private String label;
    private String type;
    private String location;

}

Action.java

package example;

import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;

@XmlType(namespace="http://www.netbeans.org/ns/freeform-project/1")
public class Action {

    @XmlAttribute
    private String name;

    private List<String> target;
}

Demo.java

package example;

import java.io.FileInputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {

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

        FileInputStream xml = new FileInputStream("src/forum32/input.xml");
        Project project = (Project) jc.createUnmarshaller().unmarshal(xml);

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

Чтобы использовать MOXy JAXB, вам нужно добавить файл jaxb.properties в классы вашей модели со следующей записью:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
0 голосов
/ 04 августа 2010

Вы можете реализовать классы конвертера, если хотите управлять XML, используемым для сериализации (или уже определили схему XML). Но XStream проще всего использовать, если вы принимаете кодировку по умолчанию (или, возможно, просто слегка ее адаптируете). Тогда вам нужно немного кода - но вы должны принять генерируемый им XML.

...