提问人:BATMAN_2008 提问时间:3/21/2023 更新时间:11/21/2023 访问量:183
如何在 Jakarta JAX-B 编组期间组合和包含来自自定义“NamespacePrefixMapper”和“HashMap”的命名空间,
How to combine and include namespaces from a custom `NamespacePrefixMapper` and a `HashMap` during Jakarta JAX-B marshalling,
问:
我正在尝试使用 the 封送一个 Java 对象,除了在生成的 XML 中包含命名空间外,一切都运行良好。Jakarta JAXB marshaller
我的类中存在很少的自定义命名空间,并且我的类中几乎没有标准命名空间,这些命名空间正在扩展.我正在尝试将它们组合起来并将其添加到 Jakarta JAXB Marshaller 中,但由于某种原因,它无法按预期工作,并且要么添加所有命名空间,要么不添加我的 HahsMap 中存在的命名空间。Map
CustomNamespaces
StandardNamespaces
NamespacePrefixMapper
CustomNamespaces
以下是我的:StandardNamespaces.class
import java.util.HashMap;
import java.util.Map;
import org.eclipse.persistence.oxm.NamespacePrefixMapper;
public class StandardNamespaces extends NamespacePrefixMapper {
public static final Map<String, String> NAMESPACE_MAP =
Map.of(
"http://www.w3.org/2001/XMLSchema-instance", "xsi",
"urn:abc:xyz:xsd:2", "abc",
"urn:abc:xyz-query:xsd:2", "abcq",
"http://www.example.org/namespaces/Standard", "sbdh",
"http://www.w3.org/2003/05/soap-envelope/", "soap");
private Map<String, String> namespaceMap;
public StandardNamespaces(final Map<String, String> namespaceMap) {
this.namespaceMap = namespaceMap;
}
public StandardNamespaces() {
this(new HashMap<>(NAMESPACE_MAP));
}
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
return namespaceMap.getOrDefault(namespaceUri, suggestion);
}
}
以下是我的,其中包含一个带有命名空间的 HashMap:CustomNamespaces.class
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class CustomNamespaces {
private static CustomNamespaces context;
private final Map<String, String> NAMESPACES;
private CustomNamespaces() {
this.NAMESPACES = new HashMap<>();
}
public static CustomNamespaces getContext() {
if (context == null) {
context = new CustomNamespaces();
}
return context;
}
// Add all the Namespaces that are defined.
public synchronized void populateNamespaces(final String namespaceURI, final String prefix) {
if (!NAMESPACES.containsKey(prefix)&& !NAMESPACES.containsValue(prefix)&& namespaceURI != null&& prefix != null) {
NAMESPACES.put(namespaceURI, prefix);
}
}
// Method that returns the saved Document namespaces.
public Map<String, String> getAllNamespaces() {
return NAMESPACES;
}
// Reset the event namespaces after completing.
public synchronized void resetAllNamespaces() {
NAMESPACES.clear();
}
}
以下是我的命名空间中存在的命名空间 HashMap 存在于我的 :CustomNamespaces
{http://ns.namespace1.com/a=a, http://ns.namespace2.com/b=b}
以下是我的编组课程:
final JAXBContext context = final JAXBContext ctx = JAXBContext.newInstance("my classes",Thread.currentThread().getContextClassLoader(),
new HashMap<>() {
{
put(
JAXBContextProperties.NAMESPACE_PREFIX_MAPPER,
new StandardNamespaces());
}
});
final Marshaller marshaller = context.createMarshaller();;
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, //Trying different method);
marshaller.marshal(o, System.out);
以下是我在传递不同的 Map 或 NamespacePrefixMapper 时得到的不同输出:
- 如果我只将 传递给编组器,那么我会得到以下命名空间:
StandardNamespaces
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, new StandardNamespaces());
命名空间:
"urn:abc:xyz-query:xsd:2", "abcq",
"http://www.example.org/namespaces/Standard", "sbdh",
这是正确的,但我也想获得自定义命名空间:
{http://ns.namespace1.com/a=a, http://ns.namespace2.com/b=b}
- 为了获得自定义和标准命名空间,我尝试了以下内容:
public class CombinedNamespacePrefixMapper extends StandardNamespaces {
private Map<String, String> namespaceMap;
public CombinedNamespacePrefixMapper(final Map<String, String> namespaceMap) {
this.namespaceMap = namespaceMap;
System.out.println("All Namespaces combined : " + this.namespaceMap);
}
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
System.out.println("URI : " + namespaceUri + " Suggestion : " + suggestion);
// Check if the namespace URI is present in the map
String prefix = namespaceMap.get(namespaceUri);
if (prefix != null) {
return prefix;
}
// Use the default namespace prefix mapper for other namespace URIs
return super.getPreferredPrefix(namespaceUri, suggestion, requirePrefix);
}
}
在编组期间通过:
CombinedNamespacePrefixMapper combinedNamespacePrefixMapper = new CombinedNamespacePrefixMapper(CustomNamespaces.getContext().getAllNamespaces());
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, combinedNamespacePrefixMapper);
这只给了我以下标准命名空间:
"urn:abc:xyz-query:xsd:2", "abcq",
"http://www.example.org/namespaces/Standard", "sbdh",
我不确定为什么它会跳过自定义命名空间,即使它们存在于 .namespacesMap
CombinedNamespacePrefixMapper
3. 我尝试将它们组合起来并添加如下:
Map<String, String> combinedNamespaceMap = new HashMap<>();
combinedNamespaceMap.putAll(CustomNamespaces.getContext().getAllNamespaces());
combinedNamespaceMap.putAll(StandardNamespaces.NAMESPACE_MAP);
然后将其添加到封送程序中:
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, combinedNamespaceMap);
在这里,我得到了 和 中存在的所有命名空间。StandardNamespaces
CustomNamespace
如何仅从映射中获取相关命名空间,并从编组的 XML 中获取所有命名空间?StandardNamespaces
CustomNamespaces
我希望我的 XML 最终具有以下命名空间:
{urn:abc:xyz-query:xsd:2=abc,http://www.example.org/namespaces/Standard=sbdh,http://ns.namespace1.com/a=a, http://ns.namespace2.com/b=b}
目前它工作正常,但从 StandardNamespaces 类或 CustomNamespaces 类添加正确的命名空间。有没有办法让它按照我需要的雅加达 Jaxb 编组工作?
答: 暂无答案
评论