JAXB @XmlElementWrapper ArrayList size

时间:2015-09-30 20:08:48

标签: java xml jaxb

我有一个用JAXB加载的XML。它正确加载,但getEffectSettings()大小为0时应显示2,因为我在'settings-list'元素中有两个'effect-setting'。有任何想法吗?我能够加载并打印效果的目标属性,除了这个变量外,效果会显示出来。

XML:     

<item:item xmlns:item="http://www.swordsandsorcery.com/item" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.swordsandsorcery.com/item ../schema.xsd">
    <item:id>1</item:id>
    <item:name>Laxi's epic</item:name>
    <item:type>ONE_HANDED_AXES</item:type>
    <item:usable>true</item:usable>
    <item:use-effect-list>
        <item:effect target="com.xyz.HealEffect">
            <item:settings-list>
                <item:effect-setting>
                    <item:setting-name>amount</item:setting-name>
                    <item:setting-value>10</item:setting-value>
                </item:effect-setting>
                <item:effect-setting>
                    <item:setting-name>xyz</item:setting-name>
                    <item:setting-value>10</item:setting-value>
                </item:effect-setting>
            </item:settings-list>
        </item:effect>
    </item:use-effect-list>
    <item:weight>5</item:weight>
    <item:combat-modifiers>
        <item:modifier>
            <item:attribute>ATTACK</item:attribute>
            <item:amount>1</item:amount>
        </item:modifier>
        <item:modifier>
            <item:attribute>DEFENSE</item:attribute>
            <item:amount>1</item:amount>
        </item:modifier>
        <item:modifier>
            <item:attribute>LIFE</item:attribute>
            <item:amount>3</item:amount>
        </item:modifier>
    </item:combat-modifiers>
    <item:general-modifiers>
        <item:modifier>
            <item:attribute>STRENGTH</item:attribute>
            <item:amount>1</item:amount>
        </item:modifier>
    </item:general-modifiers>
    <item:skill-modifiers>
        <item:modifier>
            <item:attribute>TWO_HANDED_CRUSHING_WEAPONS</item:attribute>
            <item:amount>2</item:amount>
        </item:modifier>
    </item:skill-modifiers>
    <item:basic-modifiers>
        <item:modifier>
            <item:attribute>MOVEMENT</item:attribute>
            <item:amount>1</item:amount>
        </item:modifier>
    </item:basic-modifiers>
    <item:general-requirements>
        <item:requirement>
            <item:attribute>DEXTERITY</item:attribute>
            <item:amount>100</item:amount>
        </item:requirement>
    </item:general-requirements>
</item:item>

路径中的节点:

RawItemDefinition.java(根节点):     包com.morethanheroic.swords.item.service.domain;

import com.morethanheroic.swords.effect.domain.Effect;
import com.morethanheroic.swords.item.domain.ItemType;

import javax.xml.bind.annotation.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@XmlRootElement(name = "item")
@XmlAccessorType(XmlAccessType.FIELD)
public class RawItemDefinition {

    private int id;
    private String name;
    private ItemType type;
    private boolean usable;
    private int weight;

    @XmlElementWrapper(name = "use-effect-list")
    @XmlElement(name = "effect")
    private ArrayList<Effect> effectList;

    @XmlElementWrapper(name = "basic-modifiers")
    @XmlElement(name = "modifier")
    private ArrayList<BasicAttributeModifierDefinition> basicModifiers;

    @XmlElementWrapper(name = "combat-modifiers")
    @XmlElement(name = "modifier")
    private ArrayList<CombatAttributeModifierDefinition> combatModifiers;

    @XmlElementWrapper(name = "general-modifiers")
    @XmlElement(name = "modifier")
    private ArrayList<GeneralAttributeModifierDefinition> generalModifiers;

    @XmlElementWrapper(name = "skill-modifiers")
    @XmlElement(name = "modifier")
    private ArrayList<SkillAttributeModifierDefinition> skillModifiers;

    @XmlElementWrapper(name = "basic-requirements")
    @XmlElement(name = "requirement")
    private ArrayList<BasicAttributeRequirementDefinition> basicRequirements;

    @XmlElementWrapper(name = "combat-requirements")
    @XmlElement(name = "requirement")
    private ArrayList<CombatAttributeRequirementDefinition> combatRequirements;

    @XmlElementWrapper(name = "general-requirements")
    @XmlElement(name = "requirement")
    private ArrayList<GeneralAttributeRequirementDefinition> generalRequirements;

    @XmlElementWrapper(name = "skill-requirements")
    @XmlElement(name = "requirement")
    private ArrayList<SkillAttributeRequirementDefinition> skillRequirements;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public ItemType getType() {
        return type;
    }

    public int getWeight() {
        return weight;
    }

    public boolean isUsable() {
        return usable;
    }

    public String toString() {
        return "RawItemDefinition -> [id: " + id + " name: " + name + "]";
    }

    public List<BasicAttributeModifierDefinition> getBasicModifiers() {
        return basicModifiers;
    }

    public List<CombatAttributeModifierDefinition> getCombatModifiers() {
        return combatModifiers;
    }

    public List<GeneralAttributeModifierDefinition> getGeneralModifiers() {
        return generalModifiers;
    }

    public List<SkillAttributeModifierDefinition> getSkillModifiers() {
        return skillModifiers;
    }

    public List<SkillAttributeRequirementDefinition> getSkillRequirements() {
        return skillRequirements;
    }

    public List<BasicAttributeRequirementDefinition> getBasicRequirements() {
        return basicRequirements;
    }

    public List<CombatAttributeRequirementDefinition> getCombatRequirements() {
        return combatRequirements;
    }

    public List<GeneralAttributeRequirementDefinition> getGeneralRequirements() {
        return generalRequirements;
    }

    public List<AttributeRequirementDefinition> getAllRequirements() {
        List<AttributeRequirementDefinition> list = new ArrayList<>();

        if (basicRequirements != null) {
            list.addAll(basicRequirements);
        }
        if (combatRequirements != null) {
            list.addAll(combatRequirements);
        }
        if (generalRequirements != null) {
            list.addAll(generalRequirements);
        }
        if (skillRequirements != null) {
            list.addAll(skillRequirements);
        }

        return Collections.unmodifiableList(list);
    }

    public ArrayList<Effect> getEffectList() {
        return effectList;
    }
}

Effect.java:     package com.morethanheroic.swords.effect.domain;

import javax.xml.bind.annotation.*;
import java.util.ArrayList;

@XmlAccessorType(XmlAccessType.FIELD)
public class Effect {

    @XmlAttribute
    private String target;

    @XmlElementWrapper(name = "settings-list")
    @XmlElement(name = "effect-setting")
    private ArrayList<EffectSetting> effectSettings;

    public String getTarget() {
        return target;
    }

    public ArrayList<EffectSetting> getEffectSettings() {
        return effectSettings;
    }
}

EffectSetting.java:

package com.morethanheroic.swords.effect.domain;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;

@XmlAccessorType(XmlAccessType.FIELD)
public class EffectSetting {

    @XmlElement(name = "setting-name")
    private String name;

    @XmlElement(name = "setting-value")
    private String value;

    public String getName() {
        return name;
    }

    public String getValue() {
        return value;
    }
}

我使用的unmarshaller是这样的:

package com.morethanheroic.swords.definition.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class XMLDefinitionLoader {

    private static final SchemaFactory schemaFactory =  SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

    @Autowired
    private ApplicationContext applicationContext;

    public List loadDefinitions(Class clazz, String resourcePath, String schemaPath) throws JAXBException, IOException, SAXException {
        return unmarshallTargetFiles(buildUnmarshaller(clazz, schemaPath), getTargetFiles(resourcePath));
    }

    private ArrayList unmarshallTargetFiles(Unmarshaller unmarshaller, File[] files) throws JAXBException {
        ArrayList list = new ArrayList<>();

        for (File file : files) {
            list.add(unmarshaller.unmarshal(file));
        }

        return list;
    }

    private File[] getTargetFiles(String resourcePath) throws IOException {
        return applicationContext.getResource(resourcePath).getFile().listFiles();
    }

    private Unmarshaller buildUnmarshaller(Class clazz, String schemaPath) throws IOException, SAXException, JAXBException {
        Unmarshaller unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
        unmarshaller.setSchema(buildSchema(schemaPath));

        return unmarshaller;
    }

    private Schema buildSchema(String schemaPath) throws IOException, SAXException {
        return schemaFactory.newSchema(applicationContext.getResource(schemaPath).getFile());
    }
}

这就是我尝试访问效果的方法:

@PostConstruct
public void init() throws Exception {
    List<RawItemDefinition> rawItemDefinitionList = xmlDefinitionLoader.loadDefinitions(RawItemDefinition.class, "classpath:data/item/definition/", "classpath:data/item/schema.xsd");

    for (RawItemDefinition rawItemDefinition : rawItemDefinitionList) {
        if(rawItemDefinition.getEffectList() != null) {
            System.out.println("EFFECT: "+rawItemDefinition.getEffectList().get(0).getTarget());
            System.out.println("EFFECT: "+rawItemDefinition.getEffectList().get(0).getEffectSettings().size());
        }

        itemDefinitionMap.put(rawItemDefinition.getId(), new ItemDefinition(rawItemDefinition));
    }
}

1 个答案:

答案 0 :(得分:1)

您是否可以提供代码来调用getEffectSettings()以及如何进行解组(手动或任何框架?)。

<强>更新

您是否尝试将@XmlRootElement添加到EffectSetting班级?

更新2

当你发现自己时,检查你的课程包:

  

EffectEffectSetting位于除RawItemData之外的其他包中,我将package-info.java添加到RawItemData的包中。将其添加到Effect套餐后,它就开始工作了。