Java DOM弄乱我的XML头并自己添加属性

时间:2011-04-07 15:04:20

标签: java xml dom

我遇到了一个我编写的小程序的问题。它完成了我打算做的事情(添加/删除/修改属性) - 我对这部分感到非常兴奋。但是当我输出文件时,我的标题会发生变化,并且某些元素会自动添加属性。

以下是我的开始:

<!DOCTYPE TEI SYSTEM "teilite-ur.dtd">
<TEI xmlns="http://www.tei-c.org/ns/1.0">
    <teiHeader>
        <fileDesc>
...
<availability>
...

在将每个元素节点转换为包含附加属性(name = test,value = working)之后,这就是我最终的结果:

<TEI xmlns="http://www.tei-c.org/ns/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" test="working">
    <teiHeader test="working" type="text">
        <fileDesc test="working">
...
<availability default="false" status="unknown" test="working">
...

所以,简短概述:

  • !删除了DOCTYPE专线
  • xmlns:xsi ...已添加
  • type =“text”,default =“false”,status =“unknown”anchored =“true”属性是自动添加的(可能还有其他属性,但那些是突然出现在我身上的属性)。

我在这里阅读[http://stackoverflow.com/questions/2133395/remove-xml-declaration-from-the-generated-xml-document-using-java]如何防止将XML声明添加到顶端。但是,我不知道如何禁用其余的添加内容。

谢谢!

这里有一些自包含的代码,它基本上完成了我想要的(在真实程序中更多的自定义,但这不应该是相关的)以及我用来帮助构建它的相关IBM tutorial

package xml_attrib_test;

import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;

public class Main {

    public static void main(String[] args) {
        //Input
        File whichFile = new File("C:\\Users\\mw2xx\\Desktop\\proceedings.vol1.xml");

        DocumentBuilderFactory domFactory;
        DocumentBuilder builder;
        Document doc;
        XPathFactory factory;
        XPath xpath;
        XPathExpression expr;
        NodeList nodes;

        try {
            domFactory = DocumentBuilderFactory.newInstance();
            domFactory.setSchema(null);
            domFactory.setValidating(false);
            domFactory.setNamespaceAware(true);
            domFactory.setExpandEntityReferences(false);
            builder = domFactory.newDocumentBuilder();
            doc = builder.parse(whichFile);

            factory = XPathFactory.newInstance();
            xpath = factory.newXPath();
            expr = xpath.compile("//*");

            Object result = expr.evaluate(doc, XPathConstants.NODESET);
            nodes = (NodeList) result;
        } catch (Exception ex) {
            System.out.println("Error in parser.");
            return;
        }

        // Do Stuff With the XML Doc

        String attributeTag = "test";
        String attrValue = "working";

        for (int j = 0; j < nodes.getLength(); j++) {
            Node n = nodes.item(j);

            if (n.getNodeType() == Node.ELEMENT_NODE) {
                Element e = (Element) n;
                e.setAttribute(attributeTag, attrValue);
            } else if (n.getNodeType() == Node.ATTRIBUTE_NODE) {
                Attr a = (Attr) n;
                if (a.getName().equals(attributeTag)) {
                    a.setValue(attrValue);
                }
            }
        }

        // Output
        TransformerFactory tFactory;
        Transformer transformer;
        DOMSource source;
        File resultFile;
        StreamResult result;

        try {
            tFactory = TransformerFactory.newInstance();
            transformer = tFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

            source = new DOMSource(doc);
            resultFile = new File("$$$$$.tmp");
            result = new StreamResult(resultFile);
            transformer.transform(source, result);
        } catch (Exception ex) {
            System.out.println("Error in transformer.");
            return;
        }

        whichFile.delete();
        resultFile.renameTo(whichFile);

        System.out.println("Success!");
    }
}

2 个答案:

答案 0 :(得分:1)

经过几天谷歌搜索和搜索堆栈溢出后,我发现了一个类似的问题,提供了我需要的设置。

domFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

Java change and move non-standard XML file

答案 1 :(得分:0)

您使用的是标准的JDK DOM解析器吗?

如果是,那么我猜你正在使用模式进行验证,并且该模式指定了默认属性值。这可以解释:

  • 删除DOCTYPE,因为它不用于架构验证。您可以尝试拨打setValidating(true),但之后您可能需要添加EntityResolver
  • 按照XSD中的说明设置默认值,并插入支持架构验证的属性。

如果您只关心更新XML,那么答案就是避免使用架构。或者使用模式解析一次以进行验证,然后再次进行更新。