在 groovy 中筛选具有特定值的 XML 个节点

Filter XML nodes having specific values in groovy

我的要求是从输入 xml 中查找所有 uname,其中 action = eSign。

首先,我尝试了以下代码,以过滤操作不包含 != eSign

的 eSign 的父节点

但是,当我添加 != 运算符以及将 != 替换为 == 'eSign' 时,下面的代码删除了所有节点并且没有 return 任何值使用 eSign 对 return 节点进行编码。当我对代码使用 != 运算符时无法理解问题所在。

    import com.sap.gateway.ip.core.customdev.util.Message;
    import java.util.HashMap;
    import groovy.xml.XmlUtil;
    import groovy.xml.StreamingMarkupBuilder;
    import groovy.xml.*;
    
    def Message processData(Message message) 
{        
//Body       
def parsed = new XmlParser().parseText(message.body)      parsed.data.'**'.findAll { it.action.text() != 'eSign' }.each { it.parent().remove(it) }     
message.body = XmlUtil.serialize(parsed)      
return message;    
 }

输入xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DataPageRestResult>
    <responseStatus>SUCCESS</responseStatus>
    <response>
        <offset>0</offset>
        <limit>200</limit>
        <object>
            <name>doc_audit</name>
        </object>
    </response>
<data>
        <data>
            <id>40982</id>
            <timestamp>2021-09-23T10:32:28Z</timestamp>
            <uname>new.owner@dummy.com</uname>
            <action>GetDocVersion</action>   
        </data>
 <data>
            <id>20841</id>
            <timestamp>2021-08-02T21:13:08Z</timestamp>
            <uname>thomas.mark@dummy.com</uname>
            <action>eSign</action>
        </data>
 <data>
            <id>20829</id>
            <timestamp>2021-08-02T21:11:42Z</timestamp>
            <uname>Diana.Gray@dummy.com</uname>
            <action>MDWTaskCompletion</action>         
        </data>
 <data>
            <id>20834</id>
            <timestamp>2021-08-02T21:12:25Z</timestamp>
            <uname>Mark.Robin@dummy.com</uname>
            <action>eSign</action>       
        </data>
 <data>
            <id>20829</id>
            <timestamp>2021-08-02T21:11:42Z</timestamp>
            <uname>Tray.cook@dummy.com</uname>
            <action>MDWTaskCompletion</action>       
        </data>
      <data>
            <id>20830</id>
            <timestamp>2021-08-02T21:11:42Z</timestamp>
            <uname>Zen.Fest@dummy.com</uname>
            <action>eSign</action>        
        </data>
    </data>
</DataPageRestResult>

您应该可以这样做:

Message processData(Message message) {
    def parsed = new XmlParser().parseText(message.body)
    parsed.data.'**'.findAll { it.action.text() == 'eSign' }.each { it.parent().remove(it) }
    message.body = XmlUtil.serialize(parsed)
    message
}

考虑将“数据”Node 强制转换为 Collection 以利用 Collection#removeAll

import groovy.xml.XmlUtil

class Example {

    public static class Message {
        String body
    }
    
    private static final XmlParser XML_PARSER = new XmlParser()
    private static final Message EXAMPLE_MESSAGE = new Message(body: '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?><DataPageRestResult><responseStatus>SUCCESS</responseStatus><response><offset>0</offset><limit>200</limit><object><name>doc_audit</name></object></response><data><data><id>40982</id><timestamp>2021-09-23T10:32:28Z</timestamp><uname>new.owner@dummy.com</uname><action>GetDocVersion</action></data><data><id>20841</id><timestamp>2021-08-02T21:13:08Z</timestamp><uname>thomas.mark@dummy.com</uname><action>eSign</action></data><data><id>20829</id><timestamp>2021-08-02T21:11:42Z</timestamp><uname>Diana.Gray@dummy.com</uname><action>MDWTaskCompletion</action></data><data><id>20834</id><timestamp>2021-08-02T21:12:25Z</timestamp><uname>Mark.Robin@dummy.com</uname><action>eSign</action></data><data><id>20829</id><timestamp>2021-08-02T21:11:42Z</timestamp><uname>Tray.cook@dummy.com</uname><action>MDWTaskCompletion</action></data><data><id>20830</id><timestamp>2021-08-02T21:11:42Z</timestamp><uname>Zen.Fest@dummy.com</uname><action>eSign</action></data></data></DataPageRestResult>''')
    
    public static Message processData(Message message) {
        def parsed = XML_PARSER.parseText(message.body)
        (parsed.'data'[0] as Collection)
            .removeAll { it."action".text() != "eSign" }
        message.body = XmlUtil.serialize(parsed)
        return message
    }
    
    public static void main(String[] args) {       
        println processData(EXAMPLE_MESSAGE).body
    }
}