【问题标题】:create xml markupBuilder based on external variables基于外部变量创建 xml markupBuilder
【发布时间】:2015-10-23 10:16:36
【问题描述】:

我在很多网站上都看到了 MarkupBuilder xml 创建器的常见用途。例如:

def xmlWriter = new StringWriter()
def xmlMarkup = new MarkupBuilder(xmlWriter)
xmlMarkup.movie(id: "2", "the godfather")
println(xmlWriter.toString())

会给出这样的:

<movie id='2'>the godfather</movie>

我的问题是:¿有没有一种好方法可以使用 MarkupBuilder 使用从方法中获取的变量来编写 xml?

我已设法使用此代码添加 root 访问权限:

createXml(root){
    def xmlWriter = new StringWriter()
    def xmlMarkupBuilder = new MarkupBuilder(xmlStringWriter)
    xmlMarkupBuilder.createNode(root)
    xmlMarkupBuilder.nodeCompleted(null,root)
}

但我很确定必须有另一种干净的方法来做到这一点。如果我只知道父节点的名称,如何添加新节点?

我最终用 java DocumentBuilder 做这个,

    XmlData(xmlPath, rootNodeName){
       this.xmlPath = xmlPath
       xmlDoc =    DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()
       def rootNode=xmlDoc.createElement(rootNodeName)
       xmlDoc.appendChild(rootNode)
   }

    def addNode(parentNodeName,nodeName,nodeValue,attributes){
       def newNode = xmlDoc.createElement(nodeName)
       if(nodeValue!=null){
          def newTextNode = xmlDoc.createTextNode(nodeValue)
          newNode.appendChild(newTextNode)
       }
       if(attributes!=null){
          attributes.each{key,value ->
            newNode.setAttribute($key,$value)
          }
       }
       def nodeList = xmlDoc.getElementsByTagName(parentNodeName)
       nodeList.item(nodeList.getLength()-1).appendChild(newNode)
   }

但是,如果有一种更简洁的方法可以使用 MarkupBuilder 或 MarkupBuilderHelper 执行此操作,我会更喜欢使用那个。我想得到的代码是:

输入:

        def xmlWriter = new XmlWriter("rootNode")
        xmlWriter.addNode("rootNode","",null)
        xmlWriter.addNode("rootNode","child2",null)
        xmlWriter.addNode("child1","child11","text1")
        xmlWriter.addNode("child1","child12","text2")
        xmlWriter.addNode("child2","child21","text3")
        xmlWriter.addNode("child2","child22","text4")

方法:

class XmlWriter{
    createXml(root){
    def xmlWriter = new StringWriter()
    def xmlMarkupBuilder = new MarkupBuilder(xmlStringWriter)
    xmlMarkupBuilder.createNode(root)
    xmlMarkupBuilder.nodeCompleted(null,root)
    }

    def addNode(parentNodeName,nodeName,nodeValue,attributes){
       ???
    }
}

输出:

<rootNode>
  <child1>
     <child11>test1</child11>
     </child12>test2</child12>
  </child1>
  <child2>
     <child21>test3</child21>
     </child22>test4</child22>
  </child2>
</rootNode>

注意:我没有考虑到 nodeList 项目中可能存在多个项目,因为在我的 xml 中,目前这是不可能的。

【问题讨论】:

  • 你能展示示例输入、示例方法调用和所需输出吗?

标签: xml groovy markupbuilder


【解决方案1】:

这是一种方法来做我认为你想要的......

给定一些 XML:

def xml = '''<root>
            |    <node>
            |        <anotherNode some="thing">
            |            Woo
            |        </anotherNode>
            |        <stuff>
            |        </stuff>
            |    <node>
            |    </node>
            |        <anotherNode some="thing">
            |            Woo
            |        </anotherNode>
            |        <stuff>
            |        </stuff>
            |    </node>
            |</root>'''.stripMargin()

并给出父节点的名称,新的子节点的名称,它的属性和文本内容:

def parentName = 'stuff'
def nodeName = 'things'
def nodeContent = 'text'
def attributes = [ tim: 'yates' ]

我们可以用XmlParser解析XML

import groovy.xml.*

def root = new XmlParser().parseText(xml)

然后找到所有名为parentName 的节点,并为每个节点附加一个新节点:

root.'**'.findAll { it.name() == parentName }
         .each {
             it.appendNode(new Node(it, nodeName, attributes, nodeContent))
         }

然后,打印出 xml 应该显示它们在那里:

println XmlUtil.serialize(root)

【讨论】:

  • 好的。我认为这是正确的答案,因为正如这个答案link 所说,您不能使用 MarkupBuilder 来搜索根节点,并在扩展中搜索任何节点。因此,如果 xml si 通过 add 调用逐步增长,则必须使用 XmlSluper(或类似)类对其进行修改,以将整个 xml 结构保留在内存中。
猜你喜欢
  • 2013-05-22
  • 2021-02-09
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
  • 2021-02-10
  • 1970-01-01
  • 2023-02-06
  • 1970-01-01
相关资源
最近更新 更多