规定在JAXB中只允许一个元素实例而不使用afterUnmarshal方法

时间:2016-03-02 13:34:21

标签: java xml jaxb

我需要解组XML配置文件:

<Configuration>
    <Scenarios>
        <Scenario id="1">
            <Columns>
                <Column>COL_1</Column>
                <Column>COL_2</Column>
            </Columns>
        </Scenario>
    </Scenarios>
</Configuration>

使用这个java类:

public class Scenario
{
    @NotNull
    private String _id;

    private List<String> _columns = new ArrayList<>();

    @XmlAttribute(name = "id")
    public String getId()
    {
        return _id;
    }

    public void setId(String id)
    {
        _id = id;
    }

    @XmlElement(name = "Column")
    @XmlElementWrapper(name = "Columns")
    public List<String> getColumns()
    {
        return _columns;
    }

    public void setColumns(List<String> columns)
    {
        _columns = columns;
    }
}

我想找到一种方法来确定在验证此类时XML文件中是否多次出现Columns部分(或根本没有出现)。

例如:

<Configuration>
    <Scenarios>
        <Scenario id="1">
            <Columns>
                <Column>COL_1</Column>
            </Columns>
            <Columns>
                <Column>COL_2</Column>
            </Columns>
        </Scenario>
    </Scenarios>
</Configuration>

或者:

<Configuration>
    <Scenarios>
        <Scenario id="1">
        </Scenario>
    </Scenarios>
</Configuration>

我无法使用以下答案中建议的任何侦听器,因为JAXB解组是在我的项目所依赖的另一个框架中完成的:Stipulate that only one instance of an element is allowed in JAXB?

另一种替代方法是使用此处建议的同类afterUnmarshall方法:{{3}}但是,由于我工作的公司的一些内部不成文规则,我无法使用它。

根据我上面描述的限制,我希望能够在解组之后验证这个类,检查Columns部分是否多次出现(或者根本没有出现),然后给出相应的错误消息。 / p>

我的一位同事提供了一个解决方案,我在这里作为答案。但是,欢迎使用任何其他创意解决方案。

2 个答案:

答案 0 :(得分:0)

我的同事建议的解决方案包括使用数组而不是集合。

public class Scenario
{
    @NotNull
    private String _id;

    private String[] _columns;

    private int _columnsSectionCount = 0;

    @XmlAttribute(name = "id")
    public String getId()
    {
        return _id;
    }

    public void setId(String id)
    {
        _id = id;
    }

    @XmlElement(name = "Column")
    @XmlElementWrapper(name = "Columns")
    public String[] getColumns()
    {
        return _columns;
    }

    public void setColumns(String[] columns)
    {
        _columns = columns;

        _columnsSectionCount++;
    }

    public int getColumnsSectionCount()
    {
        return _columnsSectionCount;
    }
}

通过这种方式,我可以检查验证器类中的_columnsSectionCount,看看_columns数组是否曾被设置多次或者根本没有设置。

注意:如果_columns变量的类型保留为List,则此解决方案根本不起作用。

答案 1 :(得分:0)

我认为最简单的解决方案是使用支持xml以下的通用JAXB类,而无需任何额外的代码。

'use strict';

angular.module('myApp')
  .config(function($stateProvider) {
    $stateProvider
      .state('bookIndex', {
        url: '/book',
        referrer: 'main',
        templateUrl: 'app/book/book.html',
        controller: function($state) {
          constructor($http, $scope, socket) {
            this.$http = $http;
            this.awesomeThings = [];
            $http.get('/api/book').then(response => {
              this.awesomeThings = response.data;
              socket.syncUpdates('thing', this.awesomeThings);
            });
            $scope.$on('$destroy', function() {
              socket.unsyncUpdates('thing');
            });
          }
          addThing() {
            if (this.newThing) {
              this.$http.post('/api/book', { name: this.newThing });
              this.newThing = '';
            }
          }
          deleteThing(thing) {
            this.$http.delete('/api/book/' + thing._id);
          }
        }
      });
  });

用另一个词来编写一个简单的JAXB类,它成功地解组了这个xml示例。然后检查2个列表(列,列)的大小以确定xml文件的有效性。

验证码将如下:

<Configuration>
    <Scenarios>
        <Scenario id="1">
            <Columns>
                <Column>COL_1</Column>
                <Column>COL_2</Column>
            </Columns>
            <Columns>
                <Column>COL_3</Column>
                <Column>COL_4</Column>
            </Columns>
        </Scenario>
    </Scenarios>
</Configuration>

您可以扩展此代码以实现其他验证规则。

我希望这个答案可以帮到你。