XML解析器(Unmarshal)使用JaxB从xml文件中获取元素

Posted

技术标签:

【中文标题】XML解析器(Unmarshal)使用JaxB从xml文件中获取元素【英文标题】:XML parser (Unmarshall) using JaxB to get elemet from xml file 【发布时间】:2021-11-20 17:04:36 【问题描述】:

我是 jaxB XML 解析器的新手。我需要从元素标记中获取所有属性(idref、类型、名称、范围)** 我尝试了一些东西但得到了错误。

XML 文件

<?xml version="1.0" encoding="windows-1252"?>
    <xmi:XMIxmi:version="2.1"xmlns:uml="http://www.omg.org/spec/UML/20090901"xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmlns:thecustomprofile="http://www.sparxsystems.com/profiles/thecustomprofile/1.0" xmlns:SysML="http://www.omg.org/spec/SysML/20161101/SysML">
        <xmi:Documentation exporter="Enterprise Architect" exporterVersion="6.5" exporterID="1555"/>
            <xmi:Extension extender="Enterprise Architect" extenderID="6.5">
                <elements>
      <element xmi:idref="EAPK_5560E5AF_736A_4703_AC79_CA3FAA60984B" xmi:type="uml:Package" name="PackageView" scope="public"></element>
                    <element xmi:idref="EAPK_59058493_9220_4b05_888A_67C6854C97EC" xmi:type="uml:Package" name="Read from Communication Interface" scope="public">  
                    </element>
                    <element xmi:idref="EAID_870B8E54_0FF2_4a90_A9C1_23F477DF695F" xmi:type="uml:Activity" name="Read from communication interface" scope="public">
                    </element>
                </elements>
            </xmi:Extension>
        </xmi:XMI>

主类

public class XmlElement 
        
          public static void main(String[] args) 
        
            JAXBContext jaxbContext;
            String fileLocation = "C:\\vinoth\\XML_JaxbParser\\elements.xml";
            try (FileInputStream fileInputStream = new FileInputStream(fileLocation)) 
                System.out.println("******** PARSING START ********");
                jaxbContext = JAXBContext.newInstance(Xmi.class);
                Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
                elements elements = (elements) unmarshaller.unmarshal(fileInputStream);
                System.out.println(elements);
                System.out.println("******** PARSING DONE ********");
             catch (Exception e) 
                System.out.println("******** ERROR: SOMETHING WENT WRONG ********");
                e.printStackTrace();
            
        
        

elements.java

@XmlRootElement(name = "xmi")
    
        @XmlAccessorType(XmlAccessType.FIELD)
    
        public class Elements 
         @XmlElement(name = "elements")
          private List<Elements> elements;
          // Generate Getters and Setters...
          @Override
          public String toString() 
            return "Elements [elements="+ elements +"]";
          
        

element.java

@XmlAccessorType(XmlAccessType.FIELD)
        public class Element 
          @XmlAttribute(name = "idref")
          private String idref;
          @XmlAttribute(name = "type")
          private String type;
          @XmlAttribute(name = "name")
          private String name;
          @XmlAttribute(name = "scope")
          private String scope;
        //Generate Getters and Setters...
          @Override
          public String toString() 
            return "Element [idref=" + idref + ",type=" + type + ", name=" + name + ", scope=" + scope+ "]";
          
        
        

我需要从给定的 XML 文件中获取元素属性。我不知道我在哪里做错了。根元素和父子元素,我可以从映射部分理解错误。但我无法解决。

【问题讨论】:

错误通常会告诉你哪里出了问题。不在您的问题中包含它会使其他人更难解决问题。 XML 中元素名称和属性之间缺少一些空格。我不知道这是您真正的 XML 代码,还是只是此处的不准确复制和粘贴。 【参考方案1】:

您的 XML 文件使用了许多不同的XML namespaces, 您需要在 Java 代码中考虑。

特别注意,命名空间 URIs(例如 "http://schema.omg.org/spec/XMI/2.1") 是 唯一相关的事情。命名空间前缀(例如xmi:)不是 与Java相关。它们只是为了制作 XML 而发明的 更易于人类阅读。

我建议将所有 XML 命名空间 URI 定义为 Java 字符串内容以避免在代码中多次输入:

public class NameSpaces 
    public final static String UML = "http://www.omg.org/spec/UML/20090901";
    public final static String XMI = "http://schema.omg.org/spec/XMI/2.1";
    public final static String THE_CUSTOM_PROFILE = "http://www.sparxsystems.com/profiles/thecustomprofile/1.0";
    public final static String SYSML = "http://www.omg.org/spec/SysML/20161101/SysML";

您需要仔细查看您的 XML 内容(XML 元素 XMIDocumentationExtensionElementsElement 和 它们的 XML 属性)查看哪个 XML 命名空间在哪里使用。 然后在 all 您的 Java 类中,您需要指定正确的 @XmlAttribute@XmlElement 注释中的命名空间。 您还需要在 @XmlRootElement 中指定命名空间 您的根类的注释。 另请参阅Javadoc of the JAXB annotations。

我不会为你做所有的工作,而只是展示如何 你的根类和Element 类可能看起来像。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "XMI", namespace = NameSpaces.XMI)
public class XMI 

    @XmlAttribute(name = "version", namespace = NameSpaces.XMI)
    private String version;

    @XmlElement(name = "Documentation", namespace = NameSpaces.XMI)
    private Documentation documentation;

    @XmlElement(name = "Extension", namespace = NameSpaces.XMI)
    private Extension extension;

    // Getters, setters, toString omitted here for brevity

@XmlAccessorType(XmlAccessType.FIELD)
public class Element 

    @XmlAttribute(name = "idref", namespace = NameSpaces.XMI)
    private String idref;

    @XmlAttribute(name = "type", namespace = NameSpaces.XMI)
    private String type;

    @XmlAttribute(name = "name")
    private String name;

    @XmlAttribute(name = "scope")
    private String scope;

    // Getters, setters, toString omitted here for brevity

【讨论】:

以上是关于XML解析器(Unmarshal)使用JaxB从xml文件中获取元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 JAXB 和 Unmarshal 过早结束文件。响应中的 xml 对我来说似乎有效

jaxb unmarshal xml元素到一些字段的对象

JAXB Unmarshal 创建一个空对象

Jaxb UnMarshal 错误:意外元素(uri:“”,本地:“processedSalesOrderTypeList”)。预期的元素是

通过JAXB完成Java对象与XML之间的转换

将Java从1.8.0_45更新为1.8.0_131后,JAXB unmarshal字段为空