0

あるファイルから別のファイルに 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>

現在、このコードはすべて機能していません。誰かが私を助けることができますか?

とても有難い!

4

1 に答える 1

0

私は(私が正しく理解していれば)、次のようなものが必要だと思います:

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 ) )
  }
}
于 2013-05-02T10:33:08.207 に答える