首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SimpleXML :对多个类型使用id属性

SimpleXML :对多个类型使用id属性
EN

Stack Overflow用户
提问于 2014-06-23 11:37:37
回答 3查看 711关注 0票数 0

我使用SimpleXML将XML解析为Java对象,但无法解析该文件:

代码语言:javascript
运行
复制
<pets>
    <cats>
        <cat id="0" talk="miaou" />
        <cat id="1" talk="MIWAOUHAUOHou" />
    </cats>
    <dogs>
        <dog id="0"/>
    </dogs>
    <mine>
        <cat ref="1"/>
    </mine>
</pets>

使用这个Java类:

代码语言:javascript
运行
复制
@Default
@Root(name = "pets")
public class SimpleIds
{
    @ElementList(required = false)
    public ArrayList<Cat> cats;

    @ElementList(required = false)
    public ArrayList<Dog> dogs;

    @Root(name = "cat")
    public static class Cat
    {
        @Attribute
        public String talk;

        public void talk()
        {
            System.out.println(talk);
        }
    }

    @Root(name = "dog")
    public static class Dog
    {

    }

    @Element
    public Mine mine;

    @Root(name = "mine")
    public static class Mine
    {
        @Element
        public Cat cat;
    }
}

而这个序列化器:

代码语言:javascript
运行
复制
Strategy strategy = new CycleStrategy("id", "ref");
Serializer serializer = new Persister(strategy);
SimpleIds xml = serializer.read(SimpleIds.class, new File("simpleIds.xml"));
xml.mine.cat.talk();

这让我很不友好:

代码语言:javascript
运行
复制
org.simpleframework.xml.strategy.CycleException: Element '0' already exists

在SimpleXML中不可能使用这种xml文件吗?还是它只是一种糟糕的xml格式?

编辑:如果我把cat id="0"改成cat id="2",它的效果就像魅力.

EN

Stack Overflow用户

回答已采纳

发布于 2014-06-26 13:19:55

最后,我在W3C推荐上找到了一个答案:

文档中all attributes类型为“id”(其中包括所有xml:id属性)的值是唯一的

这意味着我输入的XML是不正确的

我不能更改它,因为我从软件中接收到它,但是我必须在读取它之前对它进行格式化(并反向写入)才能得到这样的结果:

代码语言:javascript
运行
复制
<pets>
    <cats>
        <cat id="cat-0" talk="miaou" />
        <cat id="cat-1" talk="MIWAOUHAUOHou" />
    </cats>
    <dogs>
        <dog id="dog-0"/>
    </dogs>
    <mine>
        <cat ref="cat-1"/>
    </mine>
</pets>

编辑:下面是可以在SimpleXML中为您自动完成这些工作的代码:

代码语言:javascript
运行
复制
/*
 * Copyright (C) 2014, Mathieu Lavigne <bludwarf@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 * implied. See the License for the specific language governing 
 * permissions and limitations under the License.
 */
package org.simpleframework.xml.strategy;

import static org.simpleframework.xml.strategy.Name.*;

import java.util.Map;

import org.simpleframework.xml.core.Persister;
import org.simpleframework.xml.stream.Node;
import org.simpleframework.xml.stream.NodeMap;

/**
 * CycleStrategy for SimpleXML allowing having duplicate IDs on nodes from different types.
 * 
 * <p>Known limitations : </p>
 * 
 * <ul>
 * <li>as for Legacy CycleStrategy, new ids are generated for <b>every node</b> when calling {@link Persister#write(Object, java.io.File)}
 * </ul>
 * 
 * @author bludwarf@gmail.com
 * @since 26 juin 2014
 */
public class TypedCycleStrategy extends CycleStrategy
{
    private String mark;
    private String refer;

    public TypedCycleStrategy()
    {
        this(MARK, REFER, LABEL, LENGTH);
    }

    public TypedCycleStrategy(String mark, String refer)
    {
        this(mark, refer, LABEL, LENGTH);
    }

    public TypedCycleStrategy(String mark, String refer, String label)
    {
        this(mark, refer, label, LENGTH);
    }


    public TypedCycleStrategy(String mark, String refer, String label, String length)
    {
        super(mark, refer, label, length);
        this.mark = mark;
        this.refer = refer;
    }

    public Value read(Type type, NodeMap node, Map map)
            throws Exception
    {
        // Unique id
        makeUniqueAttribute(mark, node, type);

        // Unique ref
        makeUniqueAttribute(refer, node, type);

        return super.read(type, node, map);
    }


    /**
     * @param attribute mark OR refer
     * @param node current node
     * @param type node type
     * @return the uniqueId created
     * @throws Exception
     */
    public static String makeUniqueAttribute(String attribute, NodeMap node, Type type) throws Exception
    {
        final Node entry = node.remove(attribute);
        String uniqueId = null;

        // Attribute found ?
        if (entry != null)
        {
            // Replace it to make it unique
            final String id = entry.getValue();
            uniqueId = type.getType().getName() + "-" + id;
            node.put(attribute, uniqueId);
        }

        return uniqueId;
    }

}

注意:不更改包声明!

以及相应的序列化程序:

代码语言:javascript
运行
复制
Strategy strategy = new TypedCycleStrategy("id", "ref");
Serializer serializer = new Persister(strategy);
SimpleIds xml = serializer.read(SimpleIds.class, new File("simpleIds.xml"));
xml.mine.cat.talk();
票数 0
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24364936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档