我可以使用 JAXB 将所有 namspace 定义放入顶级元素吗

发布于 2024-11-09 12:39:18 字数 1388 浏览 0 评论 0原文

使用手工编写的代码,我的 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="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);

Using handcrafted code my xml was like this:

    <?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">

Now using JAXB which is much better but although the xml is perfectly valid I need to force it to put the xmlns:ext="http://musicbrainz.org/ns/ext#-1.0" within the metadata element not the artist element for compatability with client code that I have no control over.

    <?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">

Can this be done please ?

EDIT:Worked round it with String replace because I only have to deal with one specific case

    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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

2024-11-16 12:39:18

我认为没有办法使用 JAXB 来做到这一点,但这里有一个使用 Dom4J 的快速后处理器:

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);
    }
}

哦,我刚刚意识到你需要属性,而不是元素。然而,这个改变是微不足道的,所以我会把它留给你。

I don't think there's a way to do it using JAXB, but here's a quick post-processor using Dom4J:

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);
    }
}

Oh, I just realized that you need attributes, not elements. However, the change is trivial, so I'll leave that for you.

云朵有点甜 2024-11-16 12:39:18

JAXB 中至少没有记录的功能来控制名称空间前缀声明应放置在哪个元素上。然而,您应该意识到这两个 XML 片段在语义上是相同的(命名空间前缀是否在同一节点或任何祖先上声明并不重要),因此您应该选择修复损坏的客户端代码或让某人控制客户端代码来修复它。

There is at least no documented feature in JAXB to control on which element the namespace prefix declaration should be placed. You should however be aware that the two XML snippets are semantically identical (it does not matter if the namespace prefix is declared on the same node or on any ancestor), so you should opt to fix the broken client code or get someone with control of the client code to fix it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文