Hapus tag root dari dokumen XML sebelum menambahkan XML ke file lain

Saya mencoba menambahkan beberapa potongan kode XML dari satu file ke file lainnya. Masalahnya adalah, beberapa potongan ini memiliki tag root yang tidak perlu disalin ke file XML tujuan (hal ini berlaku jika tag root sama dengan tag induk yang telah ditentukan sebelumnya). Berikut kode yang saya gunakan saat ini untuk menyisipkan cuplikan (ditulis dalam Groovy):

if (addCode.nodeName == parentTags) { //meaning the root tags shouldn't be included
    for (org.w3c.dom.Node n : addCode.childNodes) {
        //parent is a NodeList
        parent.item(parent.length - 1).appendChild(document.importNode(n, true))
    }
} else {
    parent.item(parent.length - 1).appendChild(document.importNode(addCode, true))
}

Dan untuk mengurai XML:

Document parseWithoutDTD(Reader r, boolean validating = false, boolean namespaceAware = true) {
    FactorySupport.createDocumentBuilderFactory().with { f ->
        f.namespaceAware = namespaceAware
        f.validating = validating
        f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        f.newDocumentBuilder().with { db ->
            db.parse(new InputSource(r))
        }
    }
}

Berikut ini contoh file XML yang tidak boleh menyertakan tag root:

<catalogue> <!-- shouldn't be included -->
    <message key='type_issuedate'>Date Issued</message>
    <message key='type_accessioneddate'>Date Accesioned</message>
</catalogue>

Anda mungkin telah memperhatikan masalahnya: jika saya mengabaikan tag root dari file XML untuk disalin ke file XML lainnya, tag tersebut akan memunculkan pengecualian penguraian.

EDIT: berikut adalah contoh (yang disingkat) file yang akan disisipkan:

<catalogue xml:lang="en" xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
    ...
    <message key="column4">Date</message>
    <message key="column5">Summary</message>
    <message key="column6">Actions</message>
    <message key="restore">Restore</message>
    <message key="update">Update</message>
    <!-- INSERT XML HERE -->
    ...
</catalogue>

Dan contoh XML dengan tag root untuk disertakan (dan file terkait untuk disisipkan):

XML untuk disisipkan

<dependency>
    <groupId>grID</groupId>
    <artifactId>artID</artifactId>
    <version>${version.number}</version>
</dependency>

File XML untuk dimasukkan

<?xml version="1.0" encoding="UTF-8"?>
<project>
  <dependencies>
    <dependency>
        <groupId>grID1</groupId>
        <artifactId>artID1</artifactId>
        <type>jar</type>
        <classifier>classes</classifier>
    </dependency>
    <!-- INSERT XML HERE -->
  </dependencies>
</project>

Saat ini, semua kode ini tidak berfungsi sesuai keinginan saya. Bisakah seseorang membantu saya?

Sangat dihargai!


person Pieter VDE    schedule 02.05.2013    source sumber
comment
Bisakah Anda menjelaskan lebih banyak? Apakah Anda memiliki contoh dokumen yang ingin Anda tambahkan? Dan contoh di mana tag root harus disertakan?   -  person tim_yates    schedule 02.05.2013


Jawaban (1)


Saya pikir (jika saya mengerti benar), Anda memerlukan sesuatu seperti ini:

def insert( parent, data ) {
  if( parent.name() == data.name() ) {
    data.children().each {
      parent.append it
    }
  }
  else {
    parent.append data
  }
}

Jadi, diberikan

def newdoc = '''<dependency>
               |    <groupId>grID</groupId>
               |    <artifactId>artID</artifactId>
               |    <version>${version.number}</version>
               |</dependency>'''.stripMargin()

def doc = '''<?xml version="1.0" encoding="UTF-8"?>
            |<project>
            |  <dependencies>
            |    <dependency>
            |        <groupId>grID1</groupId>
            |        <artifactId>artID1</artifactId>
            |        <type>jar</type>
            |        <classifier>classes</classifier>
            |    </dependency>
            |  </dependencies>
            |</project>'''.stripMargin()

def docnode = new XmlParser().parseText( doc )
def newnode = new XmlParser().parseText( newdoc )

// use head() as I want to add to the first dependencies node
insert( docnode.dependencies.head(), newnode )
println groovy.xml.XmlUtil.serialize( docnode )

Anda mendapatkan hasilnya:

<?xml version="1.0" encoding="UTF-8"?><project>
  <dependencies>
    <dependency>
      <groupId>grID1</groupId>
      <artifactId>artID1</artifactId>
      <type>jar</type>
      <classifier>classes</classifier>
    </dependency>
    <dependency>
      <groupId>grID</groupId>
      <artifactId>artID</artifactId>
      <version>${version.number}</version>
    </dependency>
  </dependencies>
</project>

Dan diberikan:

def newdoc = '''<catalogue>
               |    <message key='type_issuedate'>Date Issued</message>
               |    <message key='type_accessioneddate'>Date Accesioned</message>
               |</catalogue>'''.stripMargin()

def doc = '''<catalogue xml:lang="en" xmlns:i18n="http://apache.org/cocoon/i18n/2.1">
            |    <message key="column4">Date</message>
            |    <message key="column5">Summary</message>
            |    <message key="column6">Actions</message>
            |    <message key="restore">Restore</message>
            |    <message key="update">Update</message>
            |</catalogue>'''.stripMargin()

def docnode = new XmlParser().parseText( doc )
def newnode = new XmlParser().parseText( newdoc )

insert( docnode, newnode )
println groovy.xml.XmlUtil.serialize( docnode )

Anda mendapatkan:

<?xml version="1.0" encoding="UTF-8"?><catalogue xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace">
  <message key="column4">Date</message>
  <message key="column5">Summary</message>
  <message key="column6">Actions</message>
  <message key="restore">Restore</message>
  <message key="update">Update</message>
  <message key="type_issuedate">Date Issued</message>
  <message key="type_accessioneddate">Date Accesioned</message>
</catalogue>

Sunting

Oke, jika diberi info tambahan, apakah ini membantu? Mengingat string newdoc dan doc yang sama seperti di atas, skrip ini sepertinya melakukan apa yang Anda inginkan...

import groovy.xml.*
import groovy.xml.dom.*
import org.w3c.dom.Document;
import org.xml.sax.InputSource;

Document parseWithoutDTD(Reader r, boolean validating = false, boolean namespaceAware = true) {
    FactorySupport.createDocumentBuilderFactory().with { f ->
        f.namespaceAware = namespaceAware
        f.validating = validating
        f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        f.newDocumentBuilder().with { db ->
            db.parse(new InputSource(r))
        }
    }
}

def addCode  = parseWithoutDTD( new StringReader( newdoc ) ).documentElement
def document = parseWithoutDTD( new StringReader( doc ) )
def parent   = document.documentElement
def parentTags = 'catalogue'

use( DOMCategory ) {
  if( addCode.nodeName == parentTags ) {
    addCode.childNodes.each { node ->
      parent.appendChild( document.importNode( node, true ) )
    }
  }
  else {
    parent.appendChild( document.importNode( addCode, true ) )
  }
}
person tim_yates    schedule 02.05.2013
comment
Ini membingungkan saya. Apakah tidak ada solusi yang melibatkan kode yang saya gunakan? Karena menggunakan kode Anda - terima kasih untuk itu, btw! - mengharuskan saya menulis ulang banyak kode saya.. - person Pieter VDE; 02.05.2013
comment
@Dreamonic kode apa yang sudah Anda miliki? Bagaimana Anda mengurai xml? Bagaimana cara Anda memiliki variabel addCode dan parentTags? Anda tidak mengatakannya dalam pertanyaan Anda, jadi jawaban yang tepat hanyalah dugaan belaka - person tim_yates; 02.05.2013
comment
addCode (Elemen) hanyalah cuplikan XML yang akan ditambahkan parsing, tanpa validasi, termasuk namespace. parentTags hanyalah sebuah String dari file properti (misalnya dependencies bisa menjadi nilai untuk parentTags). Kode yang saya gunakan untuk menambahkan cuplikan ada di pertanyaan, blok kode teratas (disingkat agar mudah dibaca, karena memposting semua kode di sini akan menghasilkan pertanyaan yang sangat, sangat panjang). - person Pieter VDE; 02.05.2013
comment
@Dreamonic bagaimana Anda mengurai xml? - person tim_yates; 02.05.2013
comment
Menggunakan cara yang sudah Anda jelaskan sebelumnya. Saya telah memperbarui pertanyaannya :) - person Pieter VDE; 02.05.2013
comment
@Dreamonic Soz, saya lupa ;-) Jawaban yang diperbarui...apakah membantu? - person tim_yates; 02.05.2013
comment
mari kita melanjutkan diskusi ini di chat - person Pieter VDE; 02.05.2013