0

特定の XmlSlurper タグを任意の XML 文字列に置き換えようとしています。これを行うために私が思いついた最良の方法は次のとおりです。

#!/usr/bin/env グルーヴィー

import groovy.xml.StreamingMarkupBuilder

def page=new XmlSlurper(new org.cyberneko.html.parsers.SAXParser()).parseText("""
<html>
<head></head>
<body>
<one attr1='val1'>asdf</one>
<two />
<replacemewithxml />
</body>
</html>
""".trim())

import groovy.xml.XmlUtil

def closure
closure={ bind,node->
  if (node.name()=="REPLACEMEWITHXML") {
    bind.mkp.yieldUnescaped "<replacementxml>sometext</replacementxml>"
  } else {
    bind."${node.name()}"(node.attributes()) {
      mkp.yield node.text()
      node.children().each { child->
 closure(bind,child)
      }
    }
  }
}
println XmlUtil.serialize(
  new StreamingMarkupBuilder().bind { bind->
    closure(bind,page)
  }
)

ただし、唯一の問題は、 text() 要素がすべての子テキスト ノードをキャプチャしているように見えるため、次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<HTML>asdf<HEAD/>
   <BODY>asdf<ONE attr1="val1">asdf</ONE>
      <TWO/>
      <replacementxml>sometext</replacementxml>
   </BODY>
</HTML>

どんなアイデア/助けも大歓迎です。

ありがとうございました!ミーシャ

psまた、好奇心から、上記を次のように「Groovier」表記に変更すると、groovy コンパイラーは、テスト クラスの ${node.name()} メンバーにアクセスしようとしていると見なします。実際のビルダーオブジェクトをまだ渡していないときに、これが当てはまらないことを指定する方法はありますか? ありがとうございました!:)

def closure
closure={ node->
  if (node.name()=="REPLACEMEWITHXML") {
    mkp.yieldUnescaped "<replacementxml>sometext</replacementxml>"
  } else {
    "${node.name()}"(node.attributes()) {
      mkp.yield node.text()
      node.children().each { child->
 closure(child)
      }
    }
  }
}
println XmlUtil.serialize(
  new StreamingMarkupBuilder().bind { 
    closure(page)
  }
)
4

1 に答える 1

0

これが私が思いついたものです:

#!/usr/bin/env groovy

import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil

def printSlurper={page->
  println XmlUtil.serialize(
    new StreamingMarkupBuilder().bind { bind->
      mkp.yield page
    }
  )
}
def saxParser=new org.cyberneko.html.parsers.SAXParser()
saxParser.setFeature('http://xml.org/sax/features/namespaces',false)
saxParser.setFeature("http://cyberneko.org/html/features/balance-tags/document-fragment",true)

def string="TEST"
def middleClosureHelper={ builder->
  builder."${string}" {
    mkp.yieldUnescaped "<inner>XML</inner>"
  }
}

def middleClosure={ 
  MiddleClosure {
    middleClosureHelper(delegate)
  }
}

def original=new XmlSlurper(saxParser).parseText("""
<original>
<middle>
</middle>
</original>
""")

original.depthFirst().find { it.name()=='MIDDLE' }.replaceNode { node->
   mkp.yield middleClosure
}

printSlurper(original)

assert original.depthFirst().find { it.name()=='INNER' } == null
def modified=new XmlSlurper(saxParser).parseText(new StreamingMarkupBuilder().bind {mkp.yield original}.toString())
assert modified.depthFirst().find { it.name()=='INNER' } != null

スラーパーをリロードする必要がありますが、機能します。

ミーシャ

于 2010-06-14T23:48:10.153 に答える