简单的XML - 2个元素,同名不同的命名空间

时间:2016-02-01 11:18:58

标签: android xml-parsing xml-namespaces simple-framework

我需要将XML字符串解析为对象。我会使用SimpleXML但是我收到错误Duplicate annotation of name 'link' on field 'url' private java.lang.String com.example.rogedormans.xmlreader.XML.Alert.Channel.url

具有相同问题的示例XML:

<rss........>
     <channel>
         <title>The Title</title>
         <link>http://www.someurl.com</link>
         <description>Some description</description>
         <atom:link href="http://dunno.com/rss.xml" rel="self" type="application/rss+xml"/>
        ....
        ....
    </channel>
 </rss>

我搜索了很多内容,发现了Thisthisthis stackoverflow文章,但没有一个对我有用...我也读过Simple XML documentation但我可以&#39 ;让它工作。

我怎样才能同时获得&#34;链接&#34;物品进入我的物体? (我认为这是命名空间的东西,但是什么?)

代码示例会很好!!!

1 个答案:

答案 0 :(得分:2)

您可以通过为Channel类实现Converter来解决此问题。

这是一个适合你的例子。它没有任何类型的错误检查等,仅使用一个Channel减少到Atom类。但是你会看到它是如何运作的。

Channel

的班级Converter
@Root()
@Convert(Channel.ChannelConverter.class) // Specify the Converter
public class Channel
{
    @Element
    private String title;
    @Element
    private String link;
    @Element
    private String description;
    @Namespace(reference = "http://www.w3.org/2005/Atom", prefix = "atom")
    @Element()
    private AtomLink atomLink;

    // Ctor's / getter / setter ...


    static class ChannelConverter implements Converter<Channel>
    {
        @Override
        public Channel read(InputNode node) throws Exception
        {
            Channel channel = new Channel();
            InputNode child;

            // Iterate over all childs an get their values
            while( ( child = node.getNext() ) != null )
            {
                switch(child.getName())
                {
                    case "title":
                        channel.setTitle(child.getValue());
                        break;
                    case "description":
                        channel.setDescription(child.getValue());
                        break;
                    case "link":
                        /*
                         * "link" can be either a <link>...</link> or
                         * a <atom:link>...</atom:link>
                         */
                        if( child.getPrefix().equals("atom") == true )
                        {
                            AtomLink atom = new AtomLink();
                            atom.setHref(child.getAttribute("href").getValue());
                            atom.setRel(child.getAttribute("rel").getValue());
                            atom.setType(child.getAttribute("type").getValue());
                            channel.setAtomLink(atom);
                        }
                        else
                        {
                            channel.setLink(child.getValue());
                        }
                        break;
                    default:
                        throw new RuntimeException("Unknown Element found: " + child);
                }
            }

            return channel;
        }


        @Override
        public void write(OutputNode node, Channel value) throws Exception
        {
            /*
             * TODO: Implement if necessary
             */
            throw new UnsupportedOperationException("Not supported yet.");
        }

    }


    @Root
    public static class AtomLink
    {
        @Attribute
        private String href;
        @Attribute
        private String rel;
        @Attribute
        private String type;

        // Ctor's / getter / setter ...
    }
}

所有内部类也可以作为常规类实现。如果(去)序列化的事情很复杂,您也可以在Serializer内使用Converter

用法

最后一个演示:

final String xml = "     <channel>\n"
        + "         <title>The Title</title>\n"
        + "         <link>http://www.someurl.com</link>\n"
        + "         <description>Some description</description>\n"
        + "         <atom:link href=\"http://dunno.com/rss.xml\" rel=\"self\" type=\"application/rss+xml\" xmlns:atom=\"http://www.w3.org/2005/Atom\" />\n"
        + "        ....\n"
        + "        ....\n"
        + "    </channel>\n";

Serializer ser = new Persister(new AnnotationStrategy());
//                             ^----- Important! -----^
Channel c = ser.read(Channel.class, xml);
System.out.println(c);

请注意,Converter需要Strategy(有关详细信息,请参阅上面的链接);我使用了AnnotationStrategy,因为您可以简单地使用@Convert()。必须在XML中的某处定义xmlns,否则您将捕获异常;我把它放在<atom:link … />这里。

输出

Channel{title=The Title, link=http://www.someurl.com, description=Some description, atomLink=AtomLink{href=http://dunno.com/rss.xml, rel=self, type=application/rss+xml}}