-1

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

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

<?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>
4

4 回答 4

1

您可以使用 XQuery 重新排列<book/>XML 中的节点。

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'调用文件中的 XQuery reorder.xq

如果您确实需要从 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

于 2013-05-01T15:51:34.503 回答
0

以下示例读取源文件“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>
于 2013-05-01T14:51:18.880 回答
0

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

于 2013-05-01T13:58:18.207 回答
0

只需用这个更改比较器:

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

西蒙娜

于 2016-12-23T11:42:25.843 回答