简体   繁体   English

如何解组具有允许在Jibx中使用多个枚举值的属性的XML文档?

[英]How can I unmarshal an XML document with an attribute that allows multiple enumeration values in jibx?

I want to use Jibx to unmarshal the following XML (stored in a file called test.xml): 我想使用Jibx解组以下XML(存储在一个名为test.xml的文件中):

<?xml version="1.0" encoding="UTF-8"?>
<rootElement attrWithEnum="avalue anothervalue" xsi:schemaLocation="my:target:ns simple.xsd" xmlns="my:target:ns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</rootElement>

I defined the schema (in a file called simple.xsd) like so: 我定义了架构(在名为simple.xsd的文件中),如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="my:target:ns" xmlns="my:target:ns" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">            
    <xs:element name="rootElement">
        <xs:complexType>
            <xs:attribute name="attrWithEnum" use="required">
                <xs:simpleType>
                    <xs:list>
                        <xs:simpleType>
                            <xs:restriction base="xs:string">
                                <xs:enumeration value="avalue"/>
                                <xs:enumeration value="anothervalue"/>
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:list>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>    
</xs:schema>

generated Java files from it using the org.jibx.schema.codegen.CodeGen tool and wrote this test program: 使用org.jibx.schema.codegen.CodeGen工具从中生成Java文件,并编写了以下测试程序:

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;

import my.target.ns.RootElement;

public final class Program {

    public static void main(final String[] args) {                

        try {

            IBindingFactory bfact = BindingDirectory.getFactory(RootElement.class);
            IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
            FileInputStream in = new FileInputStream(new File("test.xml"));

            RootElement data = (RootElement) uctx.unmarshalDocument(in, null);

            // This is not what I was expecting. I was expecting 
            // List<RootElement.Enumeration> (or equivalent) not
            // a single RootElement.Enumeration instance
            RootElement.Enumeration attrValue = data.getAttrWithEnum();

            System.out.println(attrValue);

        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}

This program fails with the error: 该程序失败,并显示以下错误:

org.jibx.runtime.JiBXException: No match found for value 'avalue anothervalue' in enum class my.target.ns.RootElement$Enumeration org.jibx.runtime.JiBXException:在枚举类my.target.ns.RootElement $ Enumeration中找不到值'avalue anothervalue'的匹配项

If I tweak my input XML like so (ie only set a single enum value) it works (prints AVALUE ). 如果我像这样调整输入XML(即仅设置一个枚举值),它将起作用(打印AVALUE )。

<rootElement attrWithEnum="avalue" xsi:schemaLocation="my:target:ns simple.xsd" xmlns="my:target:ns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

So, it seems that jibx does not like that I want to allow a list of enumeration values (I was expecting getAttrWithEnum to return a collection but it returns a single object - see the comment in the code example above). 因此,似乎jibx不喜欢我想要允许枚举值列表(我期望getAttrWithEnum返回一个集合,但它返回一个对象-请参见上面的代码示例中的注释)。

The same XSD works fine when I use jaxb (generating the java files using xjc ), so I think my XSD is valid (though if there is a better way to define what I want, that would be fine). 当我使用jaxb (使用xjc生成Java文件)时,相同的XSD可以正常工作,所以我认为我的XSD是有效的(尽管如果有更好的方法来定义我想要的东西,那会很好)。

My question therefore is: 因此,我的问题是:

How can I unmarshal an XML document with an attribute that allows multiple enumeration values in jibx? 如何解组具有允许在Jibx中使用多个枚举值的属性的XML文档?

I generated a RootElement class with xjc from your schema. 我从架构中使用xjc生成了RootElement类。 The field for the attrWithEnum attribute became List<String> attrWithEnum which would divide each word in the attribute as a separate string in the list. attrWithEnum属性的字段变为List<String> attrWithEnum ,它将属性中的每个单词划分为列表中的单独字符串。 This would allow any string value, not only those defined in the enumeration. 这将允许任何字符串值,而不仅限于枚举中定义的那些值。

Changing it to only String attrWithEnum would of course store the attribute as is. 将其更改为仅String attrWithEnum当然可以按String attrWithEnum存储属性。

I changed the type to an enum: 我将类型更改为枚举:

enum AttrEnum {
    avalue,
    anothervalue
}
@XmlAttribute(name = "attrWithEnum", required = true)
public List<AttrEnum> attrWithEnum;

Using JAXB (I've never used Jibx) this gives me a list of only valid values. 使用JAXB(我从未使用过Jibx)可以给我一个仅有效值的列表。 Any value in the attribute that is not defined in the enumeration is returned as a null value. 枚举中未定义的属性中的任何值都将返回为null值。

Changing the field to AttrEnum attrWithEnum would only return a non-null value if the attribute only contains one valid value from the enumeration. 如果属性仅包含枚举中的一个有效值, AttrEnum attrWithEnum字段更改为AttrEnum attrWithEnum只会返回一个非空值。

So my guess is that your RootElement class defines attrWithEnum as a single enum instead of as a list of enum ( List<AttrEnum> ) 所以我的猜测是您的RootElement类将attrWithEnum定义为单个enum而不是作为枚举List<AttrEnum>List<AttrEnum>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM