Java 我可以用JAXB将所有namspace定义放在顶层元素中吗
使用手工编写的代码,我的xml如下所示:Java 我可以用JAXB将所有namspace定义放在顶层元素中吗,java,xml,namespaces,jaxb,xml-namespaces,Java,Xml,Namespaces,Jaxb,Xml Namespaces,使用手工编写的代码,我的xml如下所示: <?xml version="1.0" encoding="UTF-8"?> <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#" xmlns:ext="http://musicbrainz.org/ns/ext-1.0#"> <artist-list offset="0" count="8"> <artist type
<?xml version="1.0" encoding="UTF-8"?>
<metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#"
xmlns:ext="http://musicbrainz.org/ns/ext-1.0#">
<artist-list offset="0" count="8">
<artist type="Person" id="00ed154e-8679-42f0-8f42-e59bd7e185af"
ext:score="100">
现在使用JAXB要好得多,但尽管xml非常有效,但我需要强制它放置xmlns:ext=”http://musicbrainz.org/ns/ext#-元数据元素中的“1.0”,而不是与我无法控制的客户端代码兼容的艺术家元素
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#">
<artist-list offset="0" count="4">
<artist type="Person" id="00ed154e-8679-42f0-8f42-e59bd7e185af"
ext:score="100" xmlns:ext="http://musicbrainz.org/ns/ext#-1.0">
可以这样做吗
编辑:使用字符串替换来解决它,因为我只需要处理一个特定的案例
String xml = sw.toString();
//Remove extension namespace definition
xml=xml.replace("xmlns:ext=\"http://musicbrainz.org/ns/ext#-1.0","");
//Add it to the top instead
xml=xml.replace("<metadata xmlns=\"http://musicbrainz.org/ns/mmd-1.0#\">",
"<metadata xmlns=\"http://musicbrainz.org/ns/mmd-1.0#\" xmlns:ext=\"http://musicbrainz.org/ns/ext-1.0#\">");
//Now write out to the proper output stream
out.write(xml);
stringxml=sw.toString();
//删除扩展命名空间定义
xml=xml.replace(“xmlns:ext=\”http://musicbrainz.org/ns/ext#-1.0","");
//将其添加到顶部
xml=xml.replace(“”,
"");
//现在写出正确的输出流
out.write(xml);
JAXB中至少没有文档化的功能来控制名称空间前缀声明应该放在哪个元素上。但是,您应该知道这两个XML片段在语义上是相同的(名称空间前缀是在同一个节点上还是在任何祖先上声明并不重要),所以您应该选择修复损坏的客户机代码,或者让控制客户机代码的人来修复它。我认为没有办法使用JAXB进行修复,但这里有一个快速后处理器,使用:
publicstaticvoid-moveNameSpacesToRoot(文档){
final元素rootElement=document.getRootElement();
moveNameSpacesToRootElement(rootElement,rootElement);
}
@抑制警告(“未选中”)
私有静态void moveNameSpacesToRootElement(
元素thisElement,元素rootElement){
如果(!thisElement.equals(rootElement)){
Namespace Namespace=thisElement.getNamespace();
如果(!namespace.equals(namespace.NO_namespace)){
命名空间existingRootNamespace=
getNamespaceForPrefix(namespace.getPrefix());
if(existingRootNamespace==null){
添加(名称空间);
}
删除(名称空间);
}
}
对于(元素子元素:(列表)thisElement.elements()){
moveNameSpacesToRootElement(子元素、根元素);
}
}
哦,我刚刚意识到您需要的是属性,而不是元素。但是,更改很小,所以我将把它留给您。是的,正如我上面所说的,我知道所有这些,但是第三方客户端需要时间来更正,所以我现在需要修复现有客户端的所有usersz(我没有编写)谢谢,这是一个选项,但由于我不想引入依赖项,而且xml作为字符串发送回来,所以我可能只应用正则表达式来修复这个问题output@user我理解,但那将是一个地狱般的正则表达式:-)使用字符串替换来解决它如果在现有的elements.true,但初始xml是由jaxb生成的,并且它始终生成相同的xml,因此在这种情况下,这将始终有效。
public static void moveNameSpacesToRoot(Document document) {
final Element rootElement = document.getRootElement();
moveNameSpacesToRootElement(rootElement, rootElement);
}
@SuppressWarnings("unchecked")
private static void moveNameSpacesToRootElement(
Element thisElement, Element rootElement) {
if (!thisElement.equals(rootElement)) {
Namespace namespace = thisElement.getNamespace();
if (!namespace.equals(Namespace.NO_NAMESPACE)) {
Namespace existingRootNamespace =
rootElement.getNamespaceForPrefix(namespace.getPrefix());
if (existingRootNamespace == null) {
rootElement.add(namespace);
}
thisElement.remove(namespace);
}
}
for (Element child : (List<Element>) thisElement.elements()) {
moveNameSpacesToRootElement(child, rootElement);
}
}