【问题标题】:replace XmlSlurper tag with arbitrary XML用任意 XML 替换 XmlSlurper 标记
【发布时间】:2010-06-14 04:32:42
【问题描述】:

我正在尝试用任意 XML 字符串替换特定的 XmlSlurper 标记。我想出的最佳方法是:

#!/usr/bin/env groovy

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>

非常感谢任何想法/帮助。

谢谢! 米莎

附言另外,出于好奇,如果我将上面的内容更改为“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)
  }
)

【问题讨论】:

    标签: groovy xmlslurper markupbuilder


    【解决方案1】:

    好的,这就是我想出的:

    #!/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
    

    您必须重新加载 slurper,但它可以工作!

    米莎

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 2019-12-28
      • 2023-03-28
      相关资源
      最近更新 更多