Java 使用XOM使用名称空间生成部分XML

Java 使用XOM使用名称空间生成部分XML,java,xml,xml-namespaces,xom,Java,Xml,Xml Namespaces,Xom,虽然描述看起来很长,但实际上很简单 我需要什么 我有以下xml文档 <?xml version="1.0" encoding="UTF-8"?> <atom:feed xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:atom="http://www.w3.org/2005/Atom" type="application/

虽然描述看起来很长,但实际上很简单

我需要什么 我有以下xml文档

<?xml version="1.0" encoding="UTF-8"?>
<atom:feed xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:atom="http://www.w3.org/2005/Atom" type="application/atom+xml;type=feed">
  <atom:link rel="self" href="http://hostname/thirdparty/playlist"/>
  <atom:id>vuter id</atom:id>
  <atom:title>Untitled</atom:title>
  <opensearch:totalResults>249</opensearch:totalResults>
  <opensearch:startIndex>1</opensearch:startIndex>
  <opensearch:itemsPerPage>249</opensearch:itemsPerPage>
  <atom:entry type="application/atom+xml;type=entry">
    <atom:id>12345678</atom:id>
    <atom:title>Playlist example 1</atom:title>
    <atom:link rel="self" type="application/atom+xml;type=entry" href="http://hostname/thirdparty/playlist/2101211130000011141"/>
    <dcterms:identifier>2101211130000011141</dcterms:identifier>
  </atom:entry>
  <atom:entry type="application/atom+xml;type=entry">
    <atom:id>12345678</atom:id>
    <atom:title>Playlist example 2</atom:title>
    <atom:link rel="self" type="application/atom+xml;type=entry" href="http://hostname/thirdparty/playlist/2101211090000000341"/>
    <dcterms:identifier>2101211090000000341</dcterms:identifier>
  </atom:entry>
</atom:feed>
我只得到一个名称空间声明的xml。如下图所示

<?xml version="1.0"?>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom" type="application/atom+xml;type=entry">
    <atom:id>12345678</atom:id>
    <atom:title>Playlist example 1</atom:title>
    <atom:link rel="self" type="application/atom+xml;type=entry" href="http://hostname/thirdparty/playlist/2101211130000011141" />
    <dcterms:identifier xmlns:dcterms="http://purl.org/dc/terms/">2101211130000011141</dcterms:identifier>
</atom:entry>

12345678
播放列表示例1
2101211130000011141

问题 它只包含Atom名称空间:(因此它不是有效的XML。因为它有一个子节点dcterms:identifier,其名称空间丢失


我急需帮助才能摆脱此问题。期待任何帮助。

没有问题。dcterms命名空间在需要的位置声明:在dcterms:identifier标记中

<dcterms:identifier xmlns:dcterms="http://purl.org/dc/terms/">

事实上,您期望的xml和您得到的xml是相同的。名称空间不在同一个位置声明的事实并不影响xml内容的含义

=======更新========

我建议您解决真正的问题,即您的系统不接受有效的XML(或无法正确解释它们)。为解决您的问题,请尝试以下代码:

Element rootElem = new Builder().build(ins).getRootElement();
XPathContext xc = XPathContext.makeNamespaceContext(rootElem);    
Element firstEntry = (Element) rootElem.query("atom:entry", xc).get(0); 
Document doc = new Document((Element)firstEntry.copy());
Element root = doc.getRootElement();
recursive(root,root);

static void recursive(Element root, Element child){
        root.addNamespaceDeclaration(child.getNamespacePrefix(), child.getNamespaceURI());
        if (child.getChildElements().size()>0){
            int i = child.getChildElements().size();
            for (int k=0;k<i;k++){
                recursive(root,child.getChildElements().get(k));
            }
        }
    }
Element rootElem=newbuilder().build(ins.getRootElement();
XPathContext xc=XPathContext.makeNamespaceContext(rootElem);
Element firstEntry=(Element)rootElem.query(“atom:entry”,xc.get(0);
文档文档=新文档((元素)firstEntry.copy());
元素根=doc.getRootElement();
递归(根,根);
静态void递归(元素根、元素子级){
root.addNamespaceDeclaration(child.getNamespacePrefix(),child.getNamespaceURI());
if(child.getChildElements().size()>0){
int i=child.getChildElements().size();

对于(int k=0;k没有问题。dcterms命名空间在需要的位置声明:在dcterms:identifier标记中

<dcterms:identifier xmlns:dcterms="http://purl.org/dc/terms/">

事实上,您期望的xml和您得到的xml是相同的。名称空间不在同一个位置声明的事实并不影响xml内容的含义

=======更新========

我建议您解决真正的问题,即您的系统不接受有效的XML(或无法正确解释它们)。为解决您的问题,请尝试以下代码:

Element rootElem = new Builder().build(ins).getRootElement();
XPathContext xc = XPathContext.makeNamespaceContext(rootElem);    
Element firstEntry = (Element) rootElem.query("atom:entry", xc).get(0); 
Document doc = new Document((Element)firstEntry.copy());
Element root = doc.getRootElement();
recursive(root,root);

static void recursive(Element root, Element child){
        root.addNamespaceDeclaration(child.getNamespacePrefix(), child.getNamespaceURI());
        if (child.getChildElements().size()>0){
            int i = child.getChildElements().size();
            for (int k=0;k<i;k++){
                recursive(root,child.getChildElements().get(k));
            }
        }
    }
Element rootElem=newbuilder().build(ins.getRootElement();
XPathContext xc=XPathContext.makeNamespaceContext(rootElem);
Element firstEntry=(Element)rootElem.query(“atom:entry”,xc.get(0);
文档文档=新文档((元素)firstEntry.copy());
元素根=doc.getRootElement();
递归(根,根);
静态void递归(元素根、元素子级){
root.addNamespaceDeclaration(child.getNamespacePrefix(),child.getNamespaceURI());
if(child.getChildElements().size()>0){
int i=child.getChildElements().size();
对于(int k=0;k您想要的

doc.getRootElement().addNamespaceDeclaration("dcterms", "http://purl.org/dc/terms/");
你想要

doc.getRootElement().addNamespaceDeclaration("dcterms", "http://purl.org/dc/terms/");

是的,你是对的。但问题是,我所使用的系统要求所有的命名空间声明都在根元素上。而不是在特定的元素上。所以我需要一种方法来移动根节点上的声明。完全同意你的观点。如果我能解决“真正的问题”,没有人会比我更高兴。但这超出了我的范围。无论如何,你的解决方案看起来很有希望。我会尝试一下。我将在下周一回来。是的,你是对的。但问题是,我所使用的系统需要在根元素上进行所有命名空间声明。而不是在特定的元素上。因此,我需要一种在根节点上移动声明的方法。C我完全同意你的看法。如果我能解决“真正的问题”,没有人会比我更高兴。但这超出了我的范围。不管怎样,你的解决方案似乎很有希望。我会尝试一下。我将在下周一回来。