【问题标题】:Sort XML lines in a java list, based on tag values根据标记值对 java 列表中的 XML 行进行排序
【发布时间】:2014-07-10 10:34:46
【问题描述】:

我有一个加载了 XML 行的列表,它可以按照以下任何顺序排列...

<MAIN_TAG>
    <TAG_ONE>22</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>8888</TAG_FOUR>
    <TAG_FIVE>arcdf</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>3</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>522</TAG_FOUR>
    <TAG_FIVE>00561</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>10</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>200</TAG_FOUR>
    <TAG_FIVE>ggggg</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>1</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>951</TAG_FOUR>
    <TAG_FIVE>56756</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>35</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>071</TAG_FOUR>
    <TAG_FIVE>ds15s</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>2</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>071</TAG_FOUR>
    <TAG_FIVE>34534</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>40</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>45</TAG_FOUR>
    <TAG_FIVE>4rsss</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>42</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>35</TAG_FOUR>
    <TAG_FIVE>cdsss</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>20</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>10</TAG_FOUR>
    <TAG_FIVE>dssss</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>30</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>1</TAG_FOUR>
    <TAG_FIVE>dsdfe</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>

我希望能够根据用户传入的标签对这个 Java 列表进行排序。因此,以下内容将通过传入按“TAG_ONE”排序...

<MAIN_TAG>
    <TAG_ONE>1</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>951</TAG_FOUR>
    <TAG_FIVE>56756</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>2</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>071</TAG_FOUR>
    <TAG_FIVE>34534</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>3</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>522</TAG_FOUR>
    <TAG_FIVE>00561</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>10</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>200</TAG_FOUR>
    <TAG_FIVE>ggggg</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>20</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>10</TAG_FOUR>
    <TAG_FIVE>dssss</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>22</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>8888</TAG_FOUR>
    <TAG_FIVE>arcdf</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>30</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>1</TAG_FOUR>
    <TAG_FIVE>dsdfe</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>35</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>071</TAG_FOUR>
    <TAG_FIVE>ds15s</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>40</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>45</TAG_FOUR>
    <TAG_FIVE>4rsss</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>
<MAIN_TAG>
    <TAG_ONE>42</TAG_ONE>
    <TAG_TWO>2</TAG_TWO>
    <TAG_THREE>junk</TAG_THREE>
    <TAG_FOUR>35</TAG_FOUR>
    <TAG_FIVE>cdsss</TAG_FIVE>
    <TAG_SIX>more junk</TAG_SIX>
</MAIN_TAG>

但如果可以选择按“TAG_FOUR”进行排序就好了。

提前感谢您的帮助。

斯塔克萨姆斯

【问题讨论】:

  • 使用 XML 解析器将其转换为对象列表,然后使用各种比较器对各个字段上的对象列表进行排序。
  • 基本思路:1.解析xml 2.对解析后的xml创建的对象进行排序 3.从排序后的对象列表中生成xml。
  • 感谢大家的帮助和建议 :)

标签: java xml list sorting


【解决方案1】:

这是一个完整的解决方案。

首先我定义了 2 个非常简单的类来表示 XML 中的数据:WrapperMainTag。包装器只是将MAIN_TAG 元素包装在一个列表中,这是JAXB 所要求的。 MainTag 类只包含公共属性,与输入中出现的完全相同。

一旦输入被读取,我将按任意选择的 TAG 对其进行排序(由 int 索引标识,1 表示 TAG_ONE,2 表示 TAG_TWO 等)。排序是在Wrapper.sort() 方法中实现的,该方法将标签作为参数进行排序。

最后我简单地将结果打印到标准输出,同样使用JAXB

输入稍作修改(包裹在wrapper标签中):

<wrapper>
    <MAIN_TAG>
        <TAG_ONE>22</TAG_ONE>
        <TAG_TWO>2</TAG_TWO>
        <TAG_THREE>junk</TAG_THREE>
        <TAG_FOUR>8888</TAG_FOUR>
        <TAG_FIVE>arcdf</TAG_FIVE>
        <TAG_SIX>more junk</TAG_SIX>
    </MAIN_TAG>
    <MAIN_TAG>
        <TAG_ONE>3</TAG_ONE>
        <TAG_TWO>2</TAG_TWO>
        <TAG_THREE>junk</TAG_THREE>
        <TAG_FOUR>522</TAG_FOUR>
        <TAG_FIVE>00561</TAG_FIVE>
        <TAG_SIX>more junk</TAG_SIX>
    </MAIN_TAG>
    <!-- ...and the rest which I omit here... -->
</wrapper>

Wrapper 和 MainTag 类:

class Wrapper {
    public List< MainTag > MAIN_TAG = new ArrayList<>();

    public void sort(final int byTag) {
        Collections.sort(MAIN_TAG, new Comparator< MainTag >() {
            @Override
            public int compare(MainTag m1, MainTag m2) {
                switch (byTag) {
                    case 1: return m1.TAG_ONE.compareTo(m2.TAG_ONE);
                    case 2: return m1.TAG_TWO.compareTo(m2.TAG_TWO);
                    case 3: return m1.TAG_THREE.compareTo(m2.TAG_THREE);
                    case 4: return m1.TAG_FOUR.compareTo(m2.TAG_FOUR);
                    case 5: return m1.TAG_FIVE.compareTo(m2.TAG_FIVE);
                    case 6: return m1.TAG_SIX.compareTo(m2.TAG_SIX);
                }
                return 0;
            }
        });
    }
}

class MainTag {
    public Integer TAG_ONE;
    public Integer TAG_TWO;
    public String TAG_THREE;
    public Integer TAG_FOUR;
    public String TAG_FIVE;
    public String TAG_SIX;
}

最后如何使用它:

Wrapper w = JAXB.unmarshal(new File("input.xml"), Wrapper.class);
w.sort(1);
JAXB.marshal(w, System.out);

【讨论】:

  • 非常感谢您的解决方案:)
  • 如果这回答了您的问题,请考虑投票并接受答案。
【解决方案2】:

您也可以为此使用 xslt。您可以参数化标签以进行排序、排序顺序、类型等。但是您需要有一个根元素。我举了例子

import java.io.File;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class Test {

    public static void main(String[] args) throws Exception {
        TransformerFactory factory = TransformerFactory.newInstance();
        Source xslt = new StreamSource(new File("sort.xslt"));
        Transformer transformer = factory.newTransformer(xslt);
        Source text = new StreamSource(new File("data.xml"));
        transformer.setParameter("tagName", "TAG_ONE");
        transformer.transform(text, new StreamResult(new File("output.xml")));
        System.out.println("Done");
    }

}

sort.xslt

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:param name="tagName" />
    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort data-type="number" select="*[name() = $tagName]" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多