【问题标题】:How to convert xml node into string without changing order of attributes? [duplicate]如何在不改变属性顺序的情况下将 xml 节点转换为字符串? [复制]
【发布时间】:2014-03-29 04:46:53
【问题描述】:

我正在尝试使用以下代码将 XML 节点转换为字符串:

private String nodeToString(final Node node) {
    final StringWriter stringWriter = new StringWriter();
    try {
        final Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.INDENT, "no");
        transformer.transform(new DOMSource(node), new StreamResult(stringWriter));

    } catch (final TransformerException e) {
        JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
    }
    return stringWriter.toString();
}

我的问题是它按字母顺序格式化 XML 节点的属性。有没有我可以应用的属性来忽略节点属性的格式?

【问题讨论】:

  • @Yuvi 我认为你不能......因为属性的顺序在 xml 中不是问题......
  • @McDowell 同意它是重复的,但没有人建议如何在 java 中实现这一点,无论是否使用 DOM。如果您不知道答案,请不要将其标记为重复。
  • @Naren 没关系,如果您需要验证 XML 签名。
  • @Yuvi ok try .. 如果你得到任何阳性结果,请告诉我

标签: java xml xml-parsing


【解决方案1】:

DOM API does not preserve attribute order:

NamedNodeMaps 不按任何特定顺序维护

如果您有Node,那么您已经失去了任何属性排序。考虑这个 XML:

<?xml version="1.0" encoding="UTF-8"?>
<!-- attrs.xml -->
<attrs
  a="a"
  z="z"
  b="b"
  m="m" />

无法保证此应用程序的输出顺序:

import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;

public class Attrs {
  public static void main(String[] args) throws Exception {
    NamedNodeMap attrs = DocumentBuilderFactory.newInstance()
        .newDocumentBuilder()
        .parse("attrs.xml")
        .getElementsByTagName("attrs")
        .item(0)
        .getAttributes();
    for (int i = 0; i < attrs.getLength(); i++) {
      Attr attribute = (Attr) attrs.item(i);
      System.out.println(attribute.getName() + "=" + attribute.getValue());
    }
  }
}

如果它们是按字母顺序排列的,那么这只是实现的副作用,而不是要求。如果属性顺序对您很重要,那么您使用了错误的工具。

【讨论】:

  • 我在客户端消费xml,所以必须根据服务器创建的xml进行处理。
  • 服务器未向您发送org.w3c.dom.Document。您使用哪些 API 来解析和转换数据取决于您。标准的 Java XML API 不会做你想做的事,因为属性顺序通常无关紧要。
【解决方案2】:

我知道如何做到这一点,我已经读取了 xml 文件,并且只从该 xml 文件中读取特定节点作为字符串。并对字符串应用操作以匹配我的条件。通过这样做显然我无法利用 Parser API,但这满足了我的要求。以下是我的代码 sn-p:

/**
 * @param in InputStream of xml file
 */
private String getNodeString(InputStream in) throws IOException {

    String nodeString = "";
    InputStreamReader is = new InputStreamReader(in);
    StringBuilder sb = new StringBuilder();
    BufferedReader br = new BufferedReader(is);
    String read = br.readLine();

    String fileData;

    while (read != null) {
        //System.out.println(read);
        sb.append(read);
        read = br.readLine();
    }

    fileData = sb.toString().trim();

    // Start index of node
    int start = fileData.indexOf("<" + mSignedNode);
    // End index of node, next node name
    int end = fileData.indexOf("</Configuration>");

    nodeString = fileData.substring(start, end);
    return nodeString.trim();
}

这个方法比较脏,但是可以传递参数来查找起始索引和结束索引。 希望这会对某人有所帮助,而不仅仅是结束他们的问题;)

【讨论】:

    猜你喜欢
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 2011-08-28
    • 2013-08-30
    • 2013-06-04
    • 2011-10-05
    相关资源
    最近更新 更多