如何解析具有相同标记名的嵌套xml标记

xpszyzbs  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(530)

我没有指定数量的嵌套类别,其中包含以下项目:

<categories>
    <category>abc
        <category>cde
            <item>someid</item>
            <item>someid</item>
            <item>someid</item>
            <item>someid</item>
        </category>
    </category>
<category>xyz
   <category>zwd
       <category>hgw
           <item>someid</item>
...

结果应该是嵌套最深类别(cde或hgw)中的项目列表。棘手的是,可以有两个以上级别的类别嵌套,我想为子类别保存每个父类别。
我已经用jackson xmlmapper和objectmapper进行了一些xml解析,但是这个用例似乎遥不可及。所以我用javaxmlparser尝试了一下,但放弃了,因为代码看起来很糟糕,很难阅读。
你知道如何以更优雅的方式解决这个问题吗?

bakd9h0s

bakd9h0s1#

如果任务是从xml中快速提取一些值,那么我将使用jsoup。jsoup实际上是一个html解析器,但也能够解析xml。我不确定jsoup是否也可以验证xml模式并处理名称空间和。。。这在其他解析器中是可能的。但对我来说,读懂一些jsoup值就足够了。如果您想看看jsoup食谱或选择器语法
Maven:

<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.13.1</version>
</dependency>

使用jsoup,您的代码可能看起来像:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

public class Example {

    public static void main(String[] args) {
        String xml = "<categories>\n"
                + "    <category>abc\n"
                + "        <category>cde\n"
                + "            <item>someid_1</item>\n"
                + "            <item>someid_2</item>\n"
                + "            <item>someid_3</item>\n"
                + "            <item>someid_4</item>\n"
                + "        </category>\n"
                + "    </category>\n"
                + "    <category>xyz\n"
                + "       <category>zwd\n"
                + "          <category>hgw\n"
                + "             <item>someid_5</item>\n"
                + "          </category>\n"
                + "       </category>\n"
                + "    </category>\n"
                + " </categories>";

        Document doc = Jsoup.parse(xml, "", Parser.xmlParser());

        //if you are interested in Items only
        Elements items = doc.select("category > item");
        items.forEach(i -> {
            System.out.println("Parent text: " +i.parent().ownText());
            System.out.println("Item text: "+ i.text());
            System.out.println();
        });

        //if you are interested in categories having at least one direct item element
        Elements categories = doc.select("category:has(> item)");
        categories.forEach(c -> {
            System.out.println(c.ownText());
            Elements children = c.children();
            children.forEach(ch -> {
                System.out.println(ch.text());
            });
            System.out.println();
        });
    }

}
输出:

Parent text: cde
Item text: someid_1

Parent text: cde
Item text: someid_2

Parent text: cde
Item text: someid_3

Parent text: cde
Item text: someid_4

Parent text: hgw
Item text: someid_5

cde
someid_1
someid_2
someid_3
someid_4

hgw
someid_5

相关问题