解析xml时,在groovy中前瞻?

时间:2022-06-29 21:44:49

I'm trying to parse an xml-tree. I want to:

我正在尝试解析xml树。我想要:

  • Print a representation of the path to each item. Is there a smarter way to create the path?
  • 打印每个项目的路径表示。有没有更聪明的方法来创建路径?

  • Print the name and value of nodes with primaryType="content" (content-nodes)
  • 使用primaryType =“content”(内容节点)打印节点的名称和值

  • Found a smarter/better approach. Filters? Smarter closures?
    • Can I do it another way to lookahead
    • 我可以用另一种方式来预测

  • 找到更聪明/更好的方法。过滤器?更智能的封口?我可以用另一种方式来预测

  • This example is a simple example of a more complex real-world case I have. Searching for property-elements with primaryType="text"
  • 这个例子是我所拥有的更复杂的现实世界案例的一个简单例子。使用primaryType =“text”搜索property-elements

When running the code below I get:

运行下面的代码时,我得到:

root/
--folder1/
----folder2/
metadataitem: <- "Wrong" = not what I want
found value: findme

But I want:

但我想要:

root/
--folder1/
----folder2/
------item: <- Without "metadata"  
found value: findme
  • It would be easy to do a stringreplace on "metadata" -> "" but that no good solution.
  • 在“元数据” - >“”上做一个字符串替换很容易,但这没有好的解决方案。

  • I would also like a smarter solution if you have time.
  • 如果你有时间,我还想要一个更聪明的解决方案。

Thanks in advance!

提前致谢!

Example:

def example = '''
<node name="root">
    <property name="primaryType">
        <value>folder</value>
    </property>
    <node name="metadata">
        <property name="primaryType">
            <value>metadata</value>
        </property>
        <property name="other">
            <value>...</value>
        </property>
    </node>
    <node name="folder1">
        <property name="primaryType">
            <value>folder</value>
        </property>
        <node name="metadata">
            <property name="primaryType">
                <value>metadata</value>
            </property>
            <property name="other">
                <value>...</value>
            </property>
        </node>
        <node name="folder2">
            <property name="primaryType">
                <value>folder</value>
            </property>
            <property name="other">
                <value>...</value>
            </property>
            <node name="metadata">
                <property name="primaryType">
                    <value>metadata</value>
                </property>
                <property name="other">
                    <value>...</value>
                </property>
            </node>
            <node name="item">
                <property name="primaryType">
                    <value>content</value>
                </property>
                <property name="text">
                    <value>findme</value>
                </property>
                <property name="other">
                    <value>...</value>
                </property>
            </node>
        </node>
    </node>
</node>
'''

def xml = new XmlSlurper().parseText(example);

def listContent(node,pad) {
    node.node.property.find { it.@name == "primaryType" && it.text() == "content" }.each { 
        it.parent().property.each { property ->
            if(property.@name == "text") {
                println "" + property.parent().@name + ":"// Want: "item". Gets: "metadataitem" due to parent()
                println "found value: " + property.text()
            }
        }
    }
}

def listFolders(node,pad) {
    node.property.find { it.text() == "folder" }.each { property ->
        println "-".multiply(pad) + property.parent().@name + "/"
        listContent(property.parent(),pad) 
    }
    node.children().each { child ->
        listFolders(child, pad+2)
    }
}
listFolders(xml,0)

1 个解决方案

#1


0  

The code you provided (tweaked slightly here)

你提供的代码(稍微调整一下)

def listContent( node, pad = 0 ) {
    node.node.property.find { it.@name == "primaryType" && it.text() == "content" }.each { 
        it.parent().property.each { property ->
            if(property.@name == "text") {
                println  "${'-'*pad}${property.parent().@name}:"
                println "found value: " + property.text()
            }
        }
    }
}

def listFolders( node, pad = 0 ) {
    node.property.find { it.text() == "folder" }.each { property ->
        println "${'-'*pad}${property.parent().@name}/"
        listContent(property.parent(),pad + 2) 
    }
    node.children().each { child ->
        listFolders(child, pad+2)
    }
}
listFolders( xml )

Seems to do what you want, and prints

似乎做你想做的事,并打印

root/
--folder1/
----folder2/
------item:
found value: findme

I can't see how that differs from the requirement in the question?

我看不出这与问题中的要求有什么不同?

#1


0  

The code you provided (tweaked slightly here)

你提供的代码(稍微调整一下)

def listContent( node, pad = 0 ) {
    node.node.property.find { it.@name == "primaryType" && it.text() == "content" }.each { 
        it.parent().property.each { property ->
            if(property.@name == "text") {
                println  "${'-'*pad}${property.parent().@name}:"
                println "found value: " + property.text()
            }
        }
    }
}

def listFolders( node, pad = 0 ) {
    node.property.find { it.text() == "folder" }.each { property ->
        println "${'-'*pad}${property.parent().@name}/"
        listContent(property.parent(),pad + 2) 
    }
    node.children().each { child ->
        listFolders(child, pad+2)
    }
}
listFolders( xml )

Seems to do what you want, and prints

似乎做你想做的事,并打印

root/
--folder1/
----folder2/
------item:
found value: findme

I can't see how that differs from the requirement in the question?

我看不出这与问题中的要求有什么不同?