如何在java中用XML设置节点的文本内容?

时间:2014-12-24 09:37:28

标签: java xml

考虑一下这个例子:

<PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE" NUM_ROW="40">
    <DEFAULT>""</DEFAULT>
</PARAMETER>

<PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA" NUM_ROW="40">
    <DEFAULT></DEFAULT>
</PARAMETER>

<PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY" NUM_ROW="45" REQUIRED="true">
    <DEFAULT>"select id, name from employee"</DEFAULT>
</PARAMETER>

现在我必须删除DEFAULT标记内容中的所有双引号。我尝试了以下

NodeList nList = doc.getElementsByTagName("PARAMETER");

for (int temp = 0; temp < nList.getLength(); temp++) {
    Node nNode = nList.item(temp);

    if (nNode.getNodeType() == Node.ELEMENT_NODE) {
        Element eElement = (Element) nNode;
        NodeList nl = nNode.getChildNodes();

        for (int k = 0; k < nl.getLength(); k++) {
            if (nl.item(k).getNodeName().equals("DEFAULT")) {
                nl.item(k).setTextContent(nl.item(k).getTextContent().replaceAll("\"", ""));
            }
        }
    }
}

但它不起作用。当我打开XML文件时,它仍然包含那些双引号。我该怎么做?

而且,只要有双引号,我必须向PARAMETER元素添加另一个属性,即使用值进行编码,指示DEFAULT标记中是否存在双引号。即。

<PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE" NUM_ROW="40" encode ="true">
    <DEFAULT></DEFAULT>
</PARAMETER>

<PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA" NUM_ROW="40" encode = "false">
    <DEFAULT></DEFAULT>
</PARAMETER>

<PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY" NUM_ROW="45" REQUIRED="true" encode="true">
    <DEFAULT>select id, name from employee</DEFAULT>
</PARAMETER>

我该怎么做?

3 个答案:

答案 0 :(得分:0)

您的代码没有任何问题。您是否尝试覆盖该文件或者是否已写入新文件?

foo.xml

<PARAMETERS>
    <PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE"
        NUM_ROW="40">
        <DEFAULT>""</DEFAULT>
    </PARAMETER>

    <PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA"
        NUM_ROW="40">
        <DEFAULT></DEFAULT>
    </PARAMETER>

    <PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY"
        NUM_ROW="45" REQUIRED="true">
        <DEFAULT>"select id, name from employee"</DEFAULT>
    </PARAMETER>
</PARAMETERS>

XmlUnquoteExample.java

import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

public class XmlUnquoteExample {
    public static void main(String[] args) {
        Document doc;

        try {
            doc = readXmlFile("resources/foo.xml");
            System.out.println("<!-- BEFORE -->");
            printDocument(doc, System.out);
            removeQuotes(doc);
            System.out.println("<!-- AFTER -->");
            printDocument(doc, System.out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Document readXmlFile(String filename)
            throws ParserConfigurationException, SAXException, IOException {
        InputStream is;
        DocumentBuilderFactory factory;
        DocumentBuilder builder;

        is = ClassLoader.getSystemResourceAsStream(filename);
        factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        builder = factory.newDocumentBuilder();
        return builder.parse(new ByteArrayInputStream(toByteArray(is, 16384)));
    }

    public static byte[] toByteArray(InputStream is, int bufferSize) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[bufferSize];

        while ((nRead = is.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        buffer.flush();
        return buffer.toByteArray();
    }

    public static void printDocument(Document doc, OutputStream out)
            throws IOException, TransformerException {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(
                "{http://xml.apache.org/xslt}indent-amount", "4");

        transformer.transform(new DOMSource(doc), new StreamResult(
                new OutputStreamWriter(out, "UTF-8")));
    }

    public static void removeQuotes(Document doc) {
        NodeList nList = doc.getElementsByTagName("PARAMETER");

        for (int temp = 0; temp < nList.getLength(); temp++) {
            Node nNode = (Node) nList.item(temp);

            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                NodeList nl = nNode.getChildNodes();

                for (int k = 0; k < nl.getLength(); k++) {
                    if (nl.item(k).getNodeName().equals("DEFAULT")) {
                        nl.item(k).setTextContent(
                                nl.item(k).getTextContent()
                                        .replaceAll("\"", ""));
                    }
                }
            }
        }
    }
}

输出

<!-- BEFORE -->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PARAMETERS>
    <PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE" NUM_ROW="40">
        <DEFAULT>""</DEFAULT>
    </PARAMETER>

    <PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA" NUM_ROW="40">
        <DEFAULT/>
    </PARAMETER>

    <PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY" NUM_ROW="45" REQUIRED="true">
        <DEFAULT>"select id, name from employee"</DEFAULT>
    </PARAMETER>
</PARAMETERS>
<!-- AFTER -->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PARAMETERS>
    <PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE" NUM_ROW="40">
        <DEFAULT/>
    </PARAMETER>

    <PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA" NUM_ROW="40">
        <DEFAULT/>
    </PARAMETER>

    <PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY" NUM_ROW="45" REQUIRED="true">
        <DEFAULT>select id, name from employee</DEFAULT>
    </PARAMETER>
</PARAMETERS>

答案 1 :(得分:0)

您是否可以将修改后的文档写入某个输出文件?以下是:

TransformerFactory trf = TransformerFactory.newInstance();
Transformer transformer = trf.newTransformer();
StreamResult result = new StreamResult(new FileOutputStream( "upd.xml" ));
DOMSource source = new DOMSource( document );
transformer.transform(source, result);

对于第二个问题,跟踪存在的引号并添加属性:

Boolean quotes = false;
for( int k = 0; k < nl.getLength(); k++ ){
    String txt = nl.item(k).getTextContent();
    if( txt.indexOf('"') >= 0 ){
        quotes = true;
    }
    // ...
}
eElement.setAttribute("encode", quotes.toString() );

答案 2 :(得分:0)

您已经有了可靠的答案,但我希望使用XMLBeam来显示更短的解决方案:

public class RemoveDoubleQuotes {

public interface Projection {

    public interface Subprojection {
        @XBRead(".")
        String getValue();

        @XBWrite(".")
        void setValue(String value);
    }

    @XBRead("//DEFAULT")
    List<Subprojection> getAllDefaults();
}

public static void main(final String[] args) throws IOException {
    Projection projection = new XBProjector(Flags.TO_STRING_RENDERS_XML).io().url("resource://test.xml").read(Projection.class);
    for (Subprojection s : projection.getAllDefaults()) {
        s.setValue(s.getValue().replaceAll(Pattern.quote("\""), ""));
    }
    System.out.println(projection.toString());
}
}

这个程序用更少的代码行打印出相同的结果。