如何将两个XML元素合并为一个由XSD生成的JAXB类?
completeName Field from Your XSD Got it, let's figure out how to adjust your XSD setup so that instead of generating a class with separate firstName and lastName fields, you get a single completeName field that combines both values. Here are two practical approaches depending on your workflow:
Approach 1: Use JAXB Binding Files (Recommended for XML Compatibility)
If you need to keep compatibility with the original XML structure (that has separate firstName and lastName elements), using a JAXB binding file alongside your existing XSD is the way to go. This lets you map the two elements to a single merged field using a custom adapter.
Step 1: Keep Your Original XSD
Your existing XSD stays unchanged since it defines the XML structure you need to parse/generate:
<xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="firstName" type="xs:string"/> <xs:element name="lastName" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
Step 2: Create a JAXB Binding File (binding.xml)
This file tells the XSD-to-Java generator (like xjc) to map the two name fields to a single completeName property, using an adapter to handle the merging/splitting:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.1"> <jaxb:bindings schemaLocation="your-schema-filename.xsd"> <jaxb:bindings node="//xsd:element[@name='person']/xsd:complexType"> <!-- Define the generated class name --> <jaxb:class name="Person"/> <!-- Map individual name elements to helper properties --> <jaxb:bindings node=".//xsd:element[@name='firstName']"> <jaxb:property name="firstName" /> </jaxb:bindings> <jaxb:bindings node=".//xsd:element[@name='lastName']"> <jaxb:property name="lastName" /> </jaxb:bindings> <!-- Add the merged completeName property with an adapter --> <jaxb:bindings node="."> <jaxb:property name="completeName"> <jaxb:baseType name="java.lang.String"/> <jaxb:adapter adapter="com.yourpackage.NameAdapter"/> </jaxb:property> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
Step 3: Create the Custom Adapter Class
This adapter handles merging firstName and lastName into completeName when unmarshalling XML to Java, and splitting completeName back into the two fields when marshalling Java to XML:
package com.yourpackage; import javax.xml.bind.annotation.adapters.XmlAdapter; public class NameAdapter extends XmlAdapter<NameAdapter.NameParts, String> { // Helper class to hold the individual name parts public static class NameParts { public String firstName; public String lastName; } @Override public String unmarshal(NameParts parts) throws Exception { // Merge first and last name (adjust the separator as needed) return parts.firstName + " " + parts.lastName; } @Override public NameParts marshal(String completeName) throws Exception { NameParts parts = new NameParts(); // Split the complete name back into parts (handle edge cases like single names) String[] nameSplit = completeName.split(" ", 2); parts.firstName = nameSplit[0]; parts.lastName = nameSplit.length > 1 ? nameSplit[1] : ""; return parts; } }
Step 4: Generate the Class
Run the xjc tool with your binding file to generate the Person class with the completeName field:
xjc -b binding.xml your-schema-filename.xsd
Approach 2: Modify the XSD Directly
If you don't need to maintain compatibility with the original XML structure, you can rewrite the XSD to define a single completeName element. Note that this will change the XML format your class works with:
<xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="completeName" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
Generating a class from this XSD will give you a Person class with just the completeName string field.
内容的提问来源于stack exchange,提问作者Saurabh Prajapati

