【问题标题】:Bug on @XmlElementWrapper inside <xml-elements> MoXy?<xml-elements> MoXy 中 @XmlElementWrapper 的错误?
【发布时间】:2013-06-05 15:01:46
【问题描述】:

我发现了一个棘手的错误:

如果我将 metadata-xml-binding 定义如下

<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="package" xml-mapping-metadata-complete="true">
    <xml-schema element-form-default="QUALIFIED" />
    <java-types>
        <java-type name="SearchResult">
            <xml-root-element/>
            <java-attributes>
                <xml-element java-attribute="count"/>
                <xml-element java-attribute="requestParameters"/>
                <xml-element java-attribute="pageSize"/>
                <xml-element java-attribute="sortDirection"/>
                <xml-elements java-attribute="results">
                    <xml-element name="GaDictionaryElement" type="it.ga.model.GaDictionary">
                        <xml-element-wrapper name="GaDictionaryElementWrapper" />
                    </xml-element>
                    <xml-element name="OrganizationUnitElement" type="it.ga.model.OrganizationUnit">
                        <xml-element-wrapper name="OrganizationUnitElementWrapper" />
                    </xml-element>
                    <xml-element name="PersonElement" type="it.ga.model.Person">
                        <xml-element-wrapper name="PersonElementWrapper"  />
                    </xml-element>
                    <xml-element name="Empty" type="java.lang.String">
                        <xml-element-wrapper name="EmptyWrapper" nillable="true"/>
                    </xml-element>
                </xml-elements>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

我看到&lt;xml-element-wrapper&gt; 标记不起作用,因为它位于&lt;xml-elements&gt; 标记周围的&lt;xml-element&gt; 标记中。所以我一直在寻找一种以干净的方式解决这个问题的方法。因为当我的班级的List&lt;?&gt; 结果为空时,我需要一个空节点。 一个非常糟糕的解决方法是为List&lt;?&gt; 结果创建许多不同的绑定文件,但我不喜欢这样! 此外,是否有人尝试创建一个对实现特定接口的类有用的绑定文件?例如。以某种方式,我只能看到绑定文件上定义的对象的属性并将接口的名称指定为类型?我看到了这个:[博客]:http://blog.bdoughan.com/2010/07/moxy-jaxb-map-interfaces-to-xml.html#comment-form

【问题讨论】:

  • 谢谢你的建议,但我写了 xml-elementS 来增强 S 字母的视图,因为有两个标签 &lt;xml-elements&gt; 和里面 &lt;xml-element&gt; 没有 s 字母:)

标签: eclipselink moxy


【解决方案1】:

就 MOXy 将处理的内容而言,您不得在 &lt;xml-elements&gt; 中使用 &lt;xml-element-wrapper&gt;&lt;xml-element&gt;。您可以在 &lt;xml-elements&gt; 内有一个 &lt;xml-element-wrapper

oxm.xml

<?xml version="1.0"?>
<xml-bindings 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum16943280" 
    xml-mapping-metadata-complete="true">
    <java-types>
        <java-type name="SearchResult">
            <xml-root-element/>
            <java-attributes>
                <xml-elements java-attribute="results">
                    <xml-element name="GaDictionaryElement" type="forum16943280.GaDictionary"/>
                    <xml-element name="OrganizationUnitElement" type="forum16943280.OrganizationUnit"/>
                    <xml-element-wrapper name="results"/>
                </xml-elements>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

搜索结果

package forum16943280;

import java.util.List;

public class SearchResult {

    private List<Object> results;

    public List<Object> getResults() {
        return results;
    }

    public void setResults(List<Object> results) {
        this.results = results;
    }

}

GaDictionary

package forum16943280;

public class GaDictionary {

}

组织单位

package forum16943280;

public class OrganizationUnit {

}

演示

package forum16943280;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String , Object>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum16943280/oxm.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {SearchResult.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum16943280/input.xml");
        SearchResult result = (SearchResult) unmarshaller.unmarshal(xml);

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

}

input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<searchResult>
   <results>
      <OrganizationUnitElement/>
      <OrganizationUnitElement/>
   </results>
</searchResult>

input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<searchResult>
   <results>
      <GaDictionaryElement/>
      <GaDictionaryElement/>
   </results>
</searchResult>

【讨论】:

  • 对于您的用例来说,拥有单独的列表属性可能会更好,每个属性都用&lt;xml-element&gt; 注释和自己的&lt;xml-element-wrapper&gt;你能解释一下吗?我应该为我得到的每种类型获取一个不同的包装器名称。因为List&lt;?&gt; results 总是包含相同类型的元素,例如type=it.ga.model.GaDictionaryit.ga.model.OrganizationUnit 等等...因此,如果我的 List&lt;?&gt; results 为空,我将 JaxbSearchResult 传递给编组器,其结果属性为 new ArrayList&lt;TypeThatIWantToSeeAsEmptyTag&gt; 以上指定之一。 :)
  • 我试过你的解决方案,这就是答案The content of elements must consist of well-formed character data or markup它不起作用:(
  • @Sergio - 从那个异常中听起来好像 XML 格式不正确。您能否检查 XML 是否有效。
  • 没有那个标签 &lt;xml-element-wrapper/&gt; 它可以工作。在我的下一个答案中,我编写了编组器生成的输入 xml 文件和输出
  • @Sergio - 我用更完整的例子更新了这个答案。我还使用多列表方法添加了一个新答案:stackoverflow.com/a/16965114/383861
【解决方案2】:

如果您想要单独的元素包装器,您可以按类型拆分 results 属性。

搜索结果

package forum16943280;

import java.util.List;

public class SearchResult {

    private List<GaDictionary> gaDictionaryResults;
    private List<OrganizationUnit> organizationUnitResults;

    public List<GaDictionary> getGaDictionaryResults() {
        return gaDictionaryResults;
    }

    public void setGaDictionaryResults(List<GaDictionary> results) {
        this.gaDictionaryResults = results;
    }

    public List<OrganizationUnit> getOrganizationUnitResults() {
        return organizationUnitResults;
    }

    public void setOrganizationUnitResults(
            List<OrganizationUnit> organizationUnitResults) {
        this.organizationUnitResults = organizationUnitResults;
    }

}

oxm.xml

<?xml version="1.0"?>
<xml-bindings 
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum16943280" 
    xml-mapping-metadata-complete="true">
    <java-types>
        <java-type name="SearchResult">
            <xml-root-element/>
            <java-attributes>
                <xml-element 
                    java-attribute="gaDictionaryResults"
                    name="GaDictionaryElement">
                    <xml-element-wrapper name="GaDictionaryElementWrapper"/>
                </xml-element>
                <xml-element 
                    java-attribute="organizationUnitResults"
                    name="OrganizationUnitElement">
                    <xml-element-wrapper name="OrganizationUnitElementWrapper"/>
                </xml-element>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

演示

package forum16943280;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String , Object>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum16943280/oxm.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {SearchResult.class}, properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum16943280/input.xml");
        SearchResult result = (SearchResult) unmarshaller.unmarshal(xml);

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

}

input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<searchResult>
   <GaDictionaryElementWrapper>
      <GaDictionaryElement/>
      <GaDictionaryElement/>
   </GaDictionaryElementWrapper>
</searchResult>

input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<searchResult>
   <OrganizationUnitElementWrapper>
      <OrganizationUnitElement/>
      <OrganizationUnitElement/>
   </OrganizationUnitElementWrapper>
</searchResult>

【讨论】:

  • 您是否能够在 Json 中生成它并将 List 类型的初始开头删除为 [{"id":"1"},{"id":"2"}] 而不是以这种方式 { "results" : [ { [{"id":"1"},{"id":"2"}] } ?我尝试通过将选项 JSON_INCLUDE_ROOT False 放入属性中,但我需要删除元素的名称,而不仅仅是根!不幸的是,我手动操作字符串以获得我想要的结果:(
  • @Sergio - 如果您直接编组 List,它将编组为顶级 JSON 数组。
  • 很好,但我的列表是List&lt;?&gt;,它还给了我 json 结果中的 type="Person" ! [{"type" : "person","id":"1"},{"type" : "person","id":"2"}] }
  • 我不想要“对象的类型”哪个选项可以避免它也编组和显示“类型”?
【解决方案3】:
<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="it.core.widget.dto" xml-mapping-metadata-complete="true">
    <xml-schema element-form-default="QUALIFIED" />
    <java-types>
        <java-type name="JaxbSearchResult" xml-accessor-type="NONE">
            <xml-root-element />
            <xml-type prop-order="count pageSize requestParameters sortDirection results" />
            <java-attributes>
                <xml-element java-attribute="count" />
                <xml-element java-attribute="requestParameters" />
                <xml-element java-attribute="pageSize" />
                <xml-element java-attribute="sortDirection" />
                <xml-elements java-attribute="results">
                    <xml-element name="gaDictionaryElement" type="it.ga.model.GaDictionary" />
                    <xml-element name="organizationUnitElement" type="it.ga.model.OrganizationUnit" />
                    <xml-element name="personElement" type="it.ga.model.Person" />
                    <xml-element-wrapper />
                </xml-elements>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

这是 xml,如果我删除 &lt;xml-element-wrapper /&gt; 就可以使用

此外,如果没有该标签,它会产生上述输出

<?xml version="1.0" encoding="UTF-8"?>
<jaxbSearchResult>
    <count>3</count>
    <pageSize>30</pageSize>
    <style>1</style>
    <discriminator>equipment</discriminator>
    <posting>1</posting>
    <CLEAR>1</CLEAR>
    <sortDirection> ASC </sortDirection>
    <gaDictionaryElement>
        <id>24964</id>
        <startDate>2013-03-12T00:00:00</startDate>
        <gaDictionaryMap />
        <booleanMap />
        <integerMap />
        <numberMap />
        <clobMap />
        <parentGaDictionaryLinkSet />
        <childGaDictionaryLinkSet />
        <displayValue>Equipment 2</displayValue>
    </gaDictionaryElement>
    <gaDictionaryElement>
        <id>24962</id>
        <startDate>2013-03-12T00:00:00</startDate>
        <gaDictionaryMap />
        <booleanMap />
        <integerMap />
        <numberMap />
        <clobMap />
        <parentGaDictionaryLinkSet />
        <childGaDictionaryLinkSet />
        <displayValue>Equipment 1</displayValue>
    </gaDictionaryElement>
    <gaDictionaryElement>
        <id>25185</id>
        <startDate>2013-04-22T00:00:00</startDate>
        <gaDictionaryMap />
        <booleanMap />
        <integerMap />
        <numberMap />
        <clobMap />
        <parentGaDictionaryLinkSet />
        <childGaDictionaryLinkSet />
        <displayValue>Attrezzatura test</displayValue>
    </gaDictionaryElement>
</jaxbSearchResult>

我需要相应地包装 gaDictionaryElement 已编组的类型。 任何帮助表示赞赏。 此外,是否有人尝试创建一个对实现特定接口的类有用的绑定文件?例如。以某种方式,我只能看到绑定文件上定义的对象的属性并将接口的名称指定为类型?我看过这个: [博客]:http://blog.bdoughan.com/2010/07/moxy-jaxb-map-interfaces-to-xml.html#comment-form

【讨论】:

  • 我也尝试添加 encoding="UTF-8" 但它不适用于该标签 &lt;xml-element-wrapper /&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多