我正在使用JaxB Marshalling
来创建XML
. 我的 XML 我使用该JAXB XmlAdapter
选项创建的自定义字段很少。自定义字段是使用JAXBElement
, 其中QName
参数之一创建的。
根据QName
文档,它需要 3 个参数NamespaceURI
,LocalPart
并且Prefix
. 我正在传递所有这些参数。但由于某种原因,createdXML
采用默认命名空间前缀ns0, ns1, ns2
等,而不是在QName
创建参数中提供的前缀。
一切都按预期工作,没有任何问题。我只想知道如何使我作为参数传递QName
的值而不是它自动添加的值。我知道,如果我不传递该值,那么它将采用,但在我的情况下,即使在传递了该值之后,它也会分配我想要避免的值。我尝试了很多东西,但仍然没有成功。custom prefix
default namespace prefix
prefix
default namespace prefix
custom prefix
default namespaces prefix
XML
注意:我没有使用javax Jaxb
libraray,而是使用EclipseLink Moxy
基于Jaxb
实现的libraray。
目前,创建的 XML 看起来像这样:(请注意,这些不是根元素或 XML 标头,而是从 XML 的某个部分获取的块)。
<ns0:MainField xmlns:ns0="https://google.com?xsd=google.xsd">
<ns1:SubField1 xmlns:ns1="https://fb.com?xsd=fb.xsd">
<ns2:Field1 xmlns:ns2="https://fb.com?xsd=fb.xsd">Value1</ns2:Field1>
</ns1:SubField1>
<ns3:SubField3 xmlns:ns3="https://google.com?xsd=google.xsd">SubValue3</ns3:SubField3>
</ns0:MainField>
<ns4:MainField2 xmlns:ns4="https://google.com?xsd=google.xsd">MainValue2</ns4:MainField2>
QName
根据我提供给该字段的值,我期望它看起来像这样:
<google:MainField xmlns:google="https://google.com?xsd=google.xsd">
<fb:SubField1 xmlns:fb="https://fb.com?xsd=fb.xsd">
<fb:Field1 xmlns:fb="https://fb.com?xsd=fb.xsd">Value1</fb:Field1>
</fb:SubField1>
<google:SubField3 xmlns:google="https://google.com?xsd=google.xsd">SubValue3</google:SubField3>
</google:MainField>
<google:MainField2 xmlns:google="https://google.com?xsd=google.xsd">MainValue2</google:MainField2>
以下是我的Java
课程,它正在创建QName
. 我有一个Map<String, Object>
基于它创建的值的类型QName
。一切都按预期工作,除了QName namespace prefix
.
import io.openepcis.service.jaxb.DefaultJsonSchemaNamespaceURIResolver;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.annotation.XmlAnyElement;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.xml.namespace.QName;
import org.apache.commons.lang3.NotImplementedException;
public class MapAdapter extends XmlAdapter<MapWrapper, Map<String, Object>> {
DefaultJsonSchemaNamespaceURIResolver uriResolver = new DefaultJsonSchemaNamespaceURIResolver();
@Override
public Map<String, Object> unmarshal(MapWrapper valueType) throws Exception {
throw new NotImplementedException();
}
@Override
public MapWrapper marshal(Map<String, Object> extensions) throws Exception {
if (extensions == null) {
return null;
}
MapWrapper wrapper = new MapWrapper();
List elements = new ArrayList();
//Loop through the Extensions MAP
for (Map.Entry<String, Object> property : extensions.entrySet()) {
final Optional<String> xmlNamespace = uriResolver.namespaceURIFromSchema(extension.getKey());
String namespaceURI = xmlNamespace.get();
String localPart = getLocalPart(property.getKey());
String prefix = getPrefix(property.getKey());
String label = getCleanLabel(property.getKey());
System.out.println(" namespaceURI : " + namespaceURI + " localPart : " + localPart + " prefix : " + prefix);
//If the Value type is MAP then recurse through the loop
if (property.getValue() instanceof Map) {
elements.add(new JAXBElement<MapWrapper>(new QName(namespaceURI, localPart, prefix), MapWrapper.class, marshal((Map) property.getValue())));
} else if (property.getValue() instanceof String) {
// If the Value type is String then directly create JAXBElement
elements.add(new JAXBElement<String>(new QName(namespaceURI, localPart, prefix), String.class, property.getValue().toString()));
}
}
wrapper.elements = elements;
return wrapper;
}
// Formats the complete Label for the XML tag
public static String getCleanLabel(String label) {
label = label.replaceAll("[()]", "").replaceAll("[^\\w\\s]", "_").replaceAll(" ", "_");
return label;
}
//Formats the LocalPart of the XML Tag (after ":")
public static String getLocalPart(String localPart) {
localPart = localPart.substring(localPart.indexOf(":") + 1);
return localPart;
}
//Formats the Prefix of the XML Tag (before ":")
public static String getPrefix(String prefix) {
prefix = prefix.substring(0, prefix.indexOf(":"));
return prefix;
}
}
class MapWrapper {
@XmlAnyElement
List elements;
}
class DefaultJsonSchemaNamespaceURIResolver{
private static Map<String, String> xmlNamespaces = new HashMap<String, String>();
static {
xmlNamespaces.put("google", "https://google.com");
xmlNamespaces.put("fb", "https://fb.com");
xmlNamespaces.put("insta", "https://instagram.com");
}
public Optional<String> namespaceURIFromSchema(String schemaURI) {
if (xmlNamespaces.containsKey(schemaURI)) {
return Optional.of(xmlNamespaces.get(schemaURI));
}
return Optional.empty();
}
}
以下是我在我的使用的依赖项Maven pom.xml
:
<!-- JAXB Annotations Dependencies START -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>3.0.0</version>
</dependency>
<!-- JAXB Annotations Dependencies END -->