0

説明は非常に長いように見えますが、実際には非常に簡単です。

必要なもの

次の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 には基本的に 3 つの名前空間が含まれていることに注意してください。

ここで、単一のatom:entryノードの別の xml ドキュメントを生成する必要があります。以下のように

<atom:entry type="application/atom+xml;type=entry" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:atom="http://www.w3.org/2005/Atom">
    <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>

私が得ているもの

私はXOMを使用していますが、これまで試してみました

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

そして、名前空間宣言が1つだけの次の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>

問題

Atom名前空間のみが含まれています:(したがって、有効なXMLではありません。名前空間が欠落している子ノードdcterms:identifierがあるためです。

この問題から抜け出すには、ひどく助けが必要です。どんな助けも楽しみにしています。

4

2 に答える 2

2

問題ありません。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));
            }
        }
    }

基本的に、上記のコードはすべての子を通過し、そこにある名前空間を識別し、それを名前空間宣言としてルートに追加します。私はそれを試して働きました。問題の解決策として機能することを願っています

于 2013-01-11T12:17:57.993 に答える