【问题标题】:How to re arrange child elements in an XML file using Java如何使用 Java 重新排列 XML 文件中的子元素
【发布时间】:2013-04-25 12:34:06
【问题描述】:

我有一个 xml 文件,我希望根据某些属性重新定位子元素(下面示例中的值为“id”)。 我希望以“bk103”将是 . 我的问题不在于如何对子元素进行排序(可以使用“if”条件来完成)。我想知道是否有一种方法可以解析 xml 文件并按照我希望它的顺序(比如书籍 ID 的升序)将元素重写回 xml 文件中

我应该使用什么方法来做到这一点,如果有人可以建议一种算法来做同样的事情。

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>enter code here
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
   </book>
</catalog>


Output:

<?xml version="1.0"?>
<catalog>
    <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
   </book>
<book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>


</catalog>

【问题讨论】:

  • 您当前的问题过于宽泛。将其分解成更小的部分并单独处理。
  • 我只是将帖子编辑得更具体一点。让我知道是否足够清楚
  • Sorting an XML in Java的可能重复

标签: java xml parsing dom xml-parsing


【解决方案1】:

你需要一个好的 java xml 解析器。然后您可以使用它来创建一个具有您选择的排列的新 xml 文档。实际上 MKYong 已经在 java 中覆盖了Reading from an xml documentcreating an xml document。他还介绍了检索元素属性内的值。

【讨论】:

  • 我正在使用 DOM 解析器。 java中有没有一种方法可以用来对文档中的元素进行排序?
【解决方案2】:

以下示例读取源文件“xmlFile.xml”,按字母顺序倒序排列书节点并将结果写入新文件“newXmlFile.xml”。

package org.example;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

public class XmlElementOrder {

    private static final String ID = "id";
    private static final String PATH_PREFIX = "src/main/resources/";
    private static final String SOURCE_FILE = "xmlFile.xml";
    private static final String TARGET_FILE = "newXmlFile.xml";

    public static void main(String[] args) throws JDOMException, IOException {

        File xmlFile = new File(PATH_PREFIX + SOURCE_FILE);
        SAXBuilder builder = new SAXBuilder();
        Document document = builder.build(xmlFile);

        Element rootElement = document.detachRootElement();
        List<Element> children = new ArrayList<Element>(rootElement.getChildren());
        rootElement.removeContent();

        Comparator<Element> comparator = new Comparator<Element>() {
            public int compare(Element o1, Element o2) {
                return o2.getAttributeValue(ID).compareTo(o1.getAttributeValue(ID));
            }
        };
        Collections.sort(children, comparator);

        Document newDocument = new Document(rootElement);
        rootElement.addContent(children);

        XMLOutputter xmlOutput = new XMLOutputter();
        xmlOutput.setFormat(Format.getPrettyFormat());
        xmlOutput.output(newDocument, new FileWriter(PATH_PREFIX + TARGET_FILE));

    }
}

该示例使用JDOM 库。如果您使用的是 Maven,您可以将其包含在您的 POM 中,如下所示:

<dependency>
    <groupId>org.jdom</groupId>
    <artifactId>jdom</artifactId>
    <version>2.0.2</version>
</dependency>

【讨论】:

  • 在返回 o2.getAttributeValue(ID).compareTo(o1.getAttributeValue(ID)); .如何解决?
【解决方案3】:

您可以使用 XQuery 重新排列 XML 中的 &lt;book/&gt; 节点。

declare variable $input-document external;

<catalog>
{
  for $book in doc($input-document)/catalog/book
  let $id := $book/data(@id)
  order by $id descending
  return $book
}
</catalog>

使用像 Saxon 这样的 XQuery 引擎,您可以从命令行转换 XML:

java -cp saxon9he.jar net.sf.saxon.Query input-document=input.xml reorder.xq 

saxon9he.jar 是 Saxon HE JAR,XQuery 变量 $input-document 绑定到 'input.xml',在文件 reorder.xq 中调用 XQuery。

如果您确实需要从 Java 中调用 XQuery,您可以使用 XQJ

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.namespace.QName;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;

import net.sf.saxon.xqj.SaxonXQDataSource;


public class ReorderXml {

  public static void main(String[] args) throws XQException, IOException {

    // Use XQJ to execute an XQuery with Saxon HE
    XQDataSource ds = new SaxonXQDataSource();
    XQConnection conn = ds.getConnection();

    // InputStream for the XQuery
    InputStream query = new FileInputStream("reorder.xq");

    // Create a prepared expression ...
    XQPreparedExpression exp = conn.prepareExpression(query);

    // ... and bind the path to the input document to XQuery variable $input-document
    exp.bindString(new QName("input-document"), "data/input.xml", null);

    // Execute the query and ...
    XQSequence xqs = exp.executeQuery();

    // ... print the resulting document to standard out.
    xqs.writeSequence(System.out, null);

    // Clean up (production code should do that in a finally clause!)
    xqs.close();
    conn.close();
    query.close();
  }

}

还有一些其他的 XQuery 引擎,例如 ZorbaMXQuery

【讨论】:

    【解决方案4】:

    只需用这个改变比较器:

            Comparator<Element> comparator = (op1,op2) -> op2.getChildText(ID).compareTo(op1.getChildText(ID));    
    

    西蒙娜

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      相关资源
      最近更新 更多