unmarshall一个xml文件并用java保存到数据库中

brc7rcf0  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(424)

我将以下xml文件以java上传到unmarshall:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MyValues>
    <Type Value="ABC">
        <CustomerName>Sample</CustomerName>
        <EmailAddress>sample@abcd.com</EmailAddress>
        <PhoneNumber>1234567890</PhoneNumber>
        <HardwareKey>abc-def-123-456</HardwareKey>
    </Type>
</MyValues>

我想把这个文件的值上传到我的spring应用程序的数据库中。要解组的java代码是:

String transformedFileName = TRANSFORMED_FILE_DIRECTORY+"/"+fileName;

JAXBContext context = JAXBContext.newInstance(CustomerDetails.class);
        Unmarshaller um = context.createUnmarshaller();

        customerDetails = (CustomerDetails) um.unmarshal(new InputStreamReader(
                new FileInputStream(transformedFileName), StandardCharsets.UTF_8));

        System.out.println(customerDetails);

customerdetails.java是:

@Entity
@Table(name="customerDetails")
@EntityListeners(AuditingEntityListener.class)
public class CustomerDetails {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    private String type;

    private String hardwareKey;

    private String emailAddress;

    private Long phoneNumber;

    private String customerName;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getHardwareKey() {
        return hardwareKey;
    }

    public void setHardwareKey(String hardwareKey) {
        this.hardwareKey = hardwareKey;
    }

    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }

    public Long getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(Long phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
}

这是我在运行时遇到的错误:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"MyValues"). Expected elements are (none)

我无法更改文件值和结构,必须将文件值保存在数据库中。如何克服这个错误以及如何保存这些值?我做错什么了?

tag5nh1u

tag5nh1u1#

假设到目前为止一切正常,xml格式是固定的(而且xml的大小很小)。
(将jpa和jaxb注解混合在一起是非常可能/方便/方便的,但是xml和数据库的结构应该匹配。)
在这种情况下(结构差异太复杂/xml调整不是一种选择),我们应该:
生成jaxb类 MyValues )从(固定的,很少更新的)xml/xsd。(“用手或一些工具:https://www.google.com/search?q=jaxb+generate+classes+from+xml, https://docs.oracle.com/cd/b19306_01/appdev.102/b14252/adx_j_jaxb.htm, https://www.baeldung.com/jaxb)…直到 unmarshall() ,产生理想的结果(测试!)。
将这个/ese类签入源代码管理,并且只维护/when-xml更改。
使用此生成的类来(查找和更新现有的或?)创建
new CustomerDetails ... 比如:

JAXBContext context = JAXBContext.newInstance(MyValues.class);
 Unmarshaller um = context.createUnmarshaller();

 MyValues myValues = (MyValues) um.unmarshal(new InputStreamReader(
         new FileInputStream(transformedFileName), StandardCharsets.UTF_8));

 // get a new db id:
 CustomerDetails customerDetails = new CustomerDetails(); 

 // ... or search for existing... !? (myValues.getEmail()!?;)

 // if you want to learn about "object mappers", just do it, otherwise, you have to "manually"...:
 customerDetails.setXXX(myValues.getXXX()); // ...

// and finally do something with customerDetails... 
// like: repository.save(custpomerDetails);  
// and: LOGGER.debug("customer saved: {}", customerDetails.getId());

但是,xml元素名称 MyValues 表示xml正在“构建中”,因此请尝试将其调整为“所需”:

<?xml version="1.0" encoding="UTF-8"?>
 <!-- name space ?? -->
 <CutomerDetails>
    <type>some type</type>
    <hardwareKey>someHardwareKey</hardwareKey>
    <emailAddress>john.doe@sample.com</emailAddress>
    <phoneNumber>+12345678901</phoneNumber>
    <customerName>John Doe</customerName>
</CustomerDetails>

... 然后添加 @XmlRootElement (上图) CustomerDetails 类)和“忽略 id “通过添加 @XmlTransient (至 public void setId() …),可以使您的原始代码正常工作。

sqougxex

sqougxex2#

我猜不可能将同一个类同时用于orm和jaxb目的。
我建议使用jdom或类似的库读取xml文件,并手动将xml元素Map到customerdetail对象。像这样:

import java.io.File;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;

public class XmlParsing {
  public static void main(String[] args) throws Exception {
    Document document = new SAXBuilder().build(new File("test.xml"));
    for(Element typeElement : document.getRootElement().getChildren("Type")) {
      CustomerDetails customerDetails = new CustomerDetails();
      customerDetails.setType(typeElement.getAttributeValue("Value"));
      customerDetails.setCustomerName(typeElement.getChildText("CustomerName"));
      // etc.
      // save customerDetails to database
    }
  }
}

相关问题