Groovy XML to CSV with deep XML structure

9nvpjoqh  于 2023-03-22  发布在  其他
关注(0)|答案(3)|浏览(167)

我需要一个groovy脚本,是转换成一个没有标题行的CSV文件的XML结构。
XML看起来像这样:

<stock>
            <field1>Header</field1>
                <field2>H1</field2>
        <positions>
              <data1>Hello</data1>
              <data2>P1</data2>
        </positions>
        <positions>
              <data1>World</data1>
              <data2>P2</data2>
        </positions>
    </stock>
    <stock>
            <field1>Header</field1>
                <field2>H2</field2>
        <positions>
              <data1>Hello</data1>
              <data2>P3</data2>
        </positions>
        <positions>
              <data1>World</data1>
              <data2>P4</data2>
        </positions>
    </stock>

我试过这个,但它不是做我需要的。

//parse input
        def parsedXml = new XmlParser().parseText(ins)
        
        def content = new XmlSlurper().parseText(ins)
        def csv = content.stock.positions.inject(header){ result, row ->
         [result, row.children().collect().join('|')].join("\n")

CSV应该是这样的

Header|H1
Hello|P1
World|P2
Header|H2
Hello|P3
World|P4

任何帮助是感激.谢谢

xytpbqjk

xytpbqjk1#

你可以遍历xml-tree并收集具有匹配名称的节点:

def ins = '''
<root>
    <stock>
        <field1>Header</field1>
        <field2>H1</field2>
        <positions>
            <data1>Hello</data1>
            <data2>P1</data2>
        </positions>
        <positions>
            <data1>World</data1>
            <data2>P2</data2>
        </positions>
    </stock>
    <stock>
        <field1>Header</field1>
        <field2>H2</field2>
        <positions>
            <data1>Hello</data1>
            <data2>P3</data2>
        </positions>
        <positions>
            <data1>World</data1>
            <data2>P4</data2>
        </positions>
    </stock>
</root>
'''
def content = new XmlSlurper().parseText(ins)

def csv = content.depthFirst()
        .findAll { it.name().matches(/(field|data).*/) }
        .collect{ it.text() }.collate(2)
        .collect { it.join("|") }.join("\n")

或者,如果您需要一种可以扩展字段和数据标记数量的通用方法:

def csv = content.depthFirst()
        .findAll { it.name() in ["stock", "positions"] }
        .collect { node -> node.children()
                    .findAll{ it.name() != "positions" }
                    .collect{ it.text() } }
        .collect { it.join("|") }.join("\n")
dddzy1tm

dddzy1tm2#

它不是超级高效的,因为它将所有内容都读入内存,但这将工作:

String ​xmlString = """<stocks><stock>             <field1>Header</field1>                 <field2>H1</field2>         <positions>               <data1>Hello</data1>               <data2>P1</data2>         </positions>         <positions>               <data1>World</data1>               <data2>P2</data2>         </positions>     </stock>     <stock>             <field1>Header</field1>                 <field2>H2</field2>         <positions>               <data1>Hello</data1>               <data2>P3</data2>         </positions>         <positions>               <data1>World</data1>               <data2>P4</data2>         </positions>     </stock>​</stocks>"""​​​
def xml = new ​XmlSlurper​().parseText( xmlString )

List<List<String>> output = []
xml.stock.each { stock ->
   output << [stock.field1.text(),stock.field2.text()]
   stock.positions.each { position ->
      output << [ position.data1.text(), position.data2.text() ]
   }
}
println( output.collect { it.join("|") }.join("\n") )
s1ag04yj

s1ag04yj3#

def csv = content.depthFirst()
    .findAll { it.name() in ["stock", "positions"] }
    .collect { node -> node.children()
                .findAll{ it.name() != "positions" }
                .collect{ it.text() } }
    .collect { it.join("|") }.join("\n")

是否也有一种方法可以动态地获取根和主体的XML注解,而不直接通过名称来指示它们?

相关问题