ลบแท็กรูทออกจากเอกสาร XML ก่อนที่จะเพิ่ม XML ลงในไฟล์อื่น

ฉันกำลังพยายามเพิ่มโค้ด XML หลายชิ้นจากไฟล์หนึ่งไปยังอีกไฟล์หนึ่ง ปัญหาคือ ชิ้นส่วนเหล่านี้บางส่วนมีแท็กรูทที่ไม่จำเป็นต้องคัดลอกลงในไฟล์ XML ปลายทาง (ซึ่งเป็นกรณีนี้หากแท็กรูทเท่ากับแท็กพาเรนต์ที่กำหนดไว้ล่วงหน้า) นี่คือโค้ดที่ฉันใช้เพื่อแทรกตัวอย่างข้อมูล (เขียนด้วย 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))
}

และเพื่อแยกวิเคราะห์ 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))
        }
    }
}

นี่คือตัวอย่างไฟล์ XML ที่ไม่ควรรวมแท็กรูท:

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

คุณอาจสังเกตเห็นปัญหา: หากฉันละแท็กรูทออกจากไฟล์ XML เพื่อคัดลอกไปยังไฟล์ XML อื่น แท็กเหล่านั้นจะส่งข้อยกเว้นการแยกวิเคราะห์

แก้ไข: นี่คือตัวอย่าง (ย่อ) ของไฟล์ที่จะแทรก:

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

และตัวอย่างของ XML ที่มีแท็กรูทที่จะรวมไว้ (และไฟล์ที่เกี่ยวข้องที่จะแทรก):

XML ที่จะแทรก

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

ไฟล์ XML ที่จะแทรกลงใน

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

ขณะนี้โค้ดทั้งหมดนี้ใช้งานไม่ได้ตามที่ฉันต้องการ ใครสามารถช่วยฉันออก?

ชื่นชมมาก!


person Pieter VDE    schedule 02.05.2013    source แหล่งที่มา
comment
คุณช่วยอธิบายเพิ่มเติมอีกหน่อยได้ไหม? คุณมีตัวอย่างเอกสารที่คุณพยายามเพิ่มหรือไม่ และตัวอย่างที่ควรรวมแท็กรูทไว้คืออะไร   -  person tim_yates    schedule 02.05.2013


คำตอบ (1)


ฉันคิดว่า (ถ้าฉันเข้าใจถูกต้อง) คุณต้องการสิ่งนี้:

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

ดังนั้นให้

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 )

คุณได้รับผลลัพธ์:

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

และให้:

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 )

คุณได้รับ:

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

แก้ไข

โอเค เมื่อได้รับข้อมูลเพิ่มเติม สิ่งนี้ช่วยได้ไหม ด้วยสตริง newdoc และ doc เดียวกันกับด้านบน สคริปต์นี้ดูเหมือนว่าจะทำสิ่งที่คุณต้องการ...

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
สิ่งนี้ทำให้ฉันสับสน ไม่มีวิธีแก้ปัญหาเกี่ยวกับโค้ดที่ฉันใช้อยู่แล้วใช่ไหม เพราะการใช้รหัสของคุณ - ขอบคุณสำหรับสิ่งนั้น แต่! - จะต้องให้ฉันเขียนโค้ดใหม่จำนวนมาก .. - person Pieter VDE; 02.05.2013
comment
@Dreamonic คุณมีรหัสอะไรอยู่แล้ว? คุณจะแยกวิเคราะห์ xml ได้อย่างไร? คุณมีตัวแปร addCode และ parentTags ได้อย่างไร คุณไม่ได้พูดในคำถาม ดังนั้นคำตอบที่เหมาะสมจึงเป็นการคาดเดาล้วนๆ - person tim_yates; 02.05.2013
comment
addCode (องค์ประกอบ) เป็นเพียงข้อมูลโค้ด XML ที่จะเพิ่มแยกวิเคราะห์ โดยไม่มีการตรวจสอบความถูกต้อง รวมถึงเนมสเปซด้วย parentTags เป็นเพียงสตริงจากไฟล์คุณสมบัติ (fe. dependencies อาจเป็นค่าสำหรับ parentTags) โค้ดที่ฉันใช้เพื่อเพิ่มตัวอย่างอยู่ในคำถาม บล็อกโค้ดยอดนิยม (ย่อให้สั้นลงเพื่อให้อ่านง่าย เนื่องจากการโพสต์โค้ดทั้งหมดที่นี่จะส่งผลให้เกิดคำถามที่ยาวมาก) - person Pieter VDE; 02.05.2013
comment
@Dreamonic คุณแยกวิเคราะห์ xml อย่างไร - person tim_yates; 02.05.2013
comment
โดยใช้วิธีการที่คุณได้อธิบายไว้ก่อนหน้านี้ ฉันได้อัปเดตคำถามแล้ว :) - person Pieter VDE; 02.05.2013
comment
@Dreamonic Soz ฉันลืม ;-) อัปเดตคำตอบแล้ว...ช่วยได้ไหม - person tim_yates; 02.05.2013
comment
ให้เราสนทนาต่อในการแชท - person Pieter VDE; 02.05.2013