简体   繁体   English

如何在 Java 中使用 SAX 解析器解析整个 XML 文档

[英]How to parse whole XML document using SAX parser in Java

So Im pretty new to Java coming from C#, They are pretty similar programming languages, so im getting a hang of it quickly, but there is a problem I have been battling with for a while, that I hope you can help me solve!所以我对来自 C# 的 Java 很陌生,它们是非常相似的编程语言,所以我很快就掌握了它,但是我一直在努力解决一个问题,希望你能帮我解决!

So Im using my SAX parser to parse the XML document, and it works fine, but Im having problems parsing the whole xml document, and don't know how to parse the attribute value in the top element.所以我使用我的 SAX 解析器来解析 XML 文档,它工作正常,但我在解析整个 xml 文档时遇到问题,并且不知道如何解析顶部元素中的属性值。

My xml document is as follows:我的xml文档如下:

我在解析来自 tecajnica 元素的属性“datum”时遇到问题

This is the code snippet where I believe the problem lies, This code works for parsing all of tecaj elements and their attributes/content values: but not "datum" attribute:这是我认为问题所在的代码片段,此代码适用于解析所有 tecaj 元素及其属性/内容值:但不是“datum”属性:

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
    this.elementStack.push(qName);
    CurrencyModel model = new CurrencyModel();

    if("tecajnica".equals(qName))
    {
        if(attributes != null)
        {
            model.setDatum(attributes.getValue(0));
        }
    }
    else if("tecaj".equals(qName))
    {
        if(attributes != null)
        {
            model.setOznaka(attributes.getValue(0));
            model.setSifra(attributes.getValue(1));
        }
    }
    this.objectStack.push(model);
}

So I have a model class that looks like this:所以我有一个 model class 看起来像这样:

  public class CurrencyModel
{
    public String getDatum() {
        return datum;
    }

    public void setDatum(String datum) {
        this.datum = datum;
    }

    public String getOznaka() {
        return oznaka;
    }

    public void setOznaka(String oznaka) {
        this.oznaka = oznaka;
    }

    public String getSifra() {
        return sifra;
    }

    public void setSifra(String sifra) {
        this.sifra = sifra;
    }

    public double getValue() {
        return value;
    }

    public void setValue(double value) {
        this.value = value;
    }

    String datum;
    String oznaka;
    String sifra;
    double value;

    @Override
    public String toString() {
        return "CurrencyModel{" +
                "datum=" + datum +
                ", oznaka='" + oznaka + '\'' +
                ", sifra='" + sifra + '\'' +
                ", value=" + value +
                '}';
    }
}

So each object of type CurrencyModel has its date property that is supposed to get the value of the attribute from its respected "tecajnica" element.因此,每个 object 类型的 CurrencyModel 都有其日期属性,该属性应该从其受尊重的“tecajnica”元素中获取属性值。 It works for all of the other properties but "Datum".它适用于除“基准”之外的所有其他属性。 At first I was parsing it as Date type, but as that didn't work I tried parsing it as a String.起初我将它解析为 Date 类型,但因为那不起作用我尝试将它解析为 String。 Now it works without any errors, but always sets the object "Datum" property to null...现在它可以正常工作,但始终将 object“Datum”属性设置为 null...

Output looks as follows: Output 看起来如下: 在此处输入图像描述

Any help and suggestions will be much appreciated!!!任何帮助和建议将不胜感激!!! Thank you in advance!先感谢您!

You can use JAXB parser instead of SAX, It converts each element tag into a Java objects and easily configurable too.您可以使用 JAXB 解析器代替 SAX,它将每个元素标记转换为 Java 对象并且也易于配置。 But we need to create classes for each element tag in the XML file as mentioned in this article https://www.javatpoint.com/jaxb-tutorial但是我们需要为XML文件中的每个元素标签创建类,如本文https://www.javatpoint.com/jaxb-tutorial

As per your data your root class will be like below:根据您的数据,您的根 class 将如下所示:

package com.a.b.c;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="DtecBs") 
public class DtecBs {
    
    private String datum;
    private List<tecjnica> tecjnicaList;
    
    @XmlAttribute
    public String getDatum() {
        return datum;
    }
    public void setDatum(String datum) {
        this.datum = datum;
    }
    
    @XmlElement(name="tecjnica")
    public List<tecjnica> getTecjnicaList() {
        return tecjnicaList;
    }
    public void setTecjnicaList(List<tecjnica> tecjnicaList) {
        this.tecjnicaList = tecjnicaList;
    }
    
}

Following method helps to convert XML into JavaObject:以下方法有助于将 XML 转换为 JavaObject:

Required parameters are:必需的参数是:

  • InputStream (Inputstream of the XML file) InputStream(XML文件的输入流)
  • Class (Class name of the root element in the XML com.abc.DtecBs ) Class(XML com.abc.DtecBs中根元素的类名)
    DtecBs dtecbsObj = (DtecBs)convertXmltoJavaObject(is,className);

    public Object convertXmltoJavaObject(InputStream is, Class className) throws JAXBException, ParserConfigurationException, SAXException {
        
        //Disable XXE
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
        spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

        //Do unmarshall operation
        Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(),new InputSource(is));
        JAXBContext jaxbContext = JAXBContext.newInstance(className);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        JAXBIntrospector ji = jaxbContext.createJAXBIntrospector();
        return ji.getValue(jaxbUnmarshaller.unmarshal(xmlSource));
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM