当前位置: 首页 > 知识库问答 >
问题:

如何根据收到的XML解编成不同的对象?

巫马俊力
2023-03-14

所以我收到了这样的XML文件:

<root>
    <user>
        <id>1234</id>
    </user>
    <XMLelements>
        ...
    </XMLelements>
</root>

注意XmlElements是一个示例标记名,每个XML文件可以有不同的名称。

因此,我认为,我的web服务工作流应该类似于:

    null
    null
    null

编辑:这个问题没有得到任何回答,也许我不清楚。我会试着解释得更好:

我有一个web服务,它正在侦听接收XML文件的url。实际上,在相同的url路径中,我的web服务接收两个不同的XML模式。我如何才能知道如何正确地执行解组操作?我的意思是,当传递不同的XML模式时,解组应该返回正确的对象。

共有1个答案

谢俊英
2023-03-14

有几种不同的方法来支持这个用例。

选项#1-DOM方法

您可以始终使用DOM解析器将XML转换为文档,对其执行XPath以获取ID元素的值,然后根据结果解封文档

选项#2-SAX方法

LookaheadUnmarshallerHandler

您可以利用SAX解析器和JAXB的UnmarshallerHandler机制,并执行以下操作:

    null
package forum13397834;

import java.util.*;
import javax.xml.bind.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

public class LookAheadUnmarshallerHandler extends DefaultHandler {

    private XMLReader xmlReader;
    private List<Event> events = new ArrayList<Event>();
    private UnmarshallerHandler unmarshallerHandler;

    public LookAheadUnmarshallerHandler(XMLReader xmlReader) {
        this.xmlReader = xmlReader;
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        events.add(new StartElement(uri, localName, qName, attributes));
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if("id".equals(localName) || "id".equals(qName)) {
            Characters characters = (Characters) events.get(events.size() - 1);
            String value = characters.getString();
            JAXBContext jc;
            try {
                if("1234".equals(value)) {
                    jc = JAXBContext.newInstance(Root1.class);
                } else if("5678".equals(value)) {
                    jc = JAXBContext.newInstance(Root2.class);
                } else {
                    jc = JAXBContext.newInstance(Root3.class);
                }
                unmarshallerHandler = jc.createUnmarshaller().getUnmarshallerHandler();
            } catch(JAXBException e) {
                throw new RuntimeException(e);
            }
            unmarshallerHandler.startDocument();
            for(Event event : events) {
                event.event(unmarshallerHandler);
            }
            unmarshallerHandler.endElement(uri, localName, qName);
            xmlReader.setContentHandler(unmarshallerHandler);
        } else {
            events.add(new EndElement(uri, localName, qName));
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        events.add(new Characters(ch, start, length));
    }

    public Object getResult() throws JAXBException {
        return unmarshallerHandler.getResult();
    }

    private static abstract class Event {

        public abstract void event(ContentHandler contentHandler) throws SAXException; 

    }

    private static class StartElement extends Event {

        private String uri;
        private String localName;
        private String qName;
        private Attributes attributes;

        public StartElement(String uri, String localName, String qName, Attributes attributes) {
            this.uri = uri;
            this.localName = localName;
            this.qName = qName;
            this.attributes = attributes;
        }

        @Override
        public void event(ContentHandler contentHandler) throws SAXException {
            contentHandler.startElement(uri, localName, qName, attributes);
        }

    }

    private static class Characters extends Event {

        private char[] ch;
        private int start;
        private int length;

        public Characters(char[] ch, int start, int length) {
            this.ch = ch;
            this.start = start;
            this.length = length;
        }

        @Override
        public void event(ContentHandler contentHandler) throws SAXException {
            contentHandler.characters(ch, start, length);
        }

        public String getString() {
            return new String(ch, start, length);
        }

    }

    private static class EndElement extends Event {

        private String uri;
        private String localName;
        private String qName;

        public EndElement(String uri, String localName, String qName) {
            this.uri = uri;
            this.localName = localName;
            this.qName = qName;
        }

        @Override
        public void event(ContentHandler contentHandler) throws SAXException {
            contentHandler.endElement(uri, localName, qName);
        }

    }

}

Usera

package forum13397834;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="root")
public class UserA {

}

用户b

package forum13397834;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="root")
public class UserB {

}

用户c

package forum13397834;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="root")
public class UserC {

}
<root>
    <user>
        <id>1234</id>
    </user>
    <XMLelements>
        ...
    </XMLelements>
</root>
package forum13397834;

import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setNamespaceAware(true);
        XMLReader xmlReader = spf.newSAXParser().getXMLReader();

        LookAheadUnmarshallerHandler handler = new LookAheadUnmarshallerHandler(xmlReader);
        xmlReader.setContentHandler(handler);
        xmlReader.parse(new InputSource("src/forum13397834/input.xml"));
        Object object = handler.getResult();
        System.out.println(object.getClass());
    }

}
class forum13397834.UserA
 类似资料:
  • 我成功地从多个wsdlendpoint使用maven-jaxb2-plugin生成java类。 这是一次执行: 这里的问题是,我有多个执行,因此生成多个类,每个执行将类保存在不同的包中。 一个B类abiret2.java在多个包中生成(因此,它来自多个wdsls) 当我执行使用这个存根的代码时,例如在单元测试中,我会得到以下异常: 我发现了一些可能的修复方法,比如在args标记下添加配置 Arg,

  • 问题内容: 我试图解析来自不同来源(我对此几乎没有控制权)的xml文件。其中大多数都使用UTF-8编码,使用以下代码段不会造成任何问题: 由于SAX默认为UTF-8,所以很好。但是,一些文档声明: 即使已声明ISO-8859-1,SAX仍默认为UTF-8。仅当我添加: SAX将使用正确的编码。 如何让SAX自动从xml声明中检测正确的编码,而无需我专门进行设置?我需要这个,因为我事先不知道文件的编

  • 问题内容: 我想解组一个包含数据集合的xml文件,像这样 我们知道这可以通过两个类完成:人员,使用Castor的人员,JAXB或其他框架。 但是,如果不编写收集类的Persons怎么办? 问题答案: 寻找一种方法来告诉Castor您希望它生成一个Person实例。 http://www.castor.org/how-to-map-a-list-at- root.html

  • 我有一个谷歌表单,它将数据收集到电子表格中(表单响应1)。因为我认为有4m行的限制,所以如何以编程方式创建新的工作表并将响应存储到新创建的工作表中。 注意:这不是将响应复制到新工作表中。

  • 假设我有一个简单的模型(Xcore语法): 我现在有三个A,创建如下: 当我试着这样比较它们的时候:

  • 我正在尝试使用匕首学习依赖注入。 我明白,在您的类中,您不会直接实例化客户机代码所依赖的对象,而是使用@inject声明它,通过模块创建ObjectGraphs,并从ObjectGraph中获取对象: 谢谢你。