gpt4 book ai didi

java - 为什么在使用 java 将字符串追加到文件的开头和结尾后,xml 文件没有正确对齐?

转载 作者:行者123 更新时间:2023-11-30 10:39:27 25 4
gpt4 key购买 nike

我已经在XML文件的开头和结尾添加了字符串,但是得到结果后对齐不正确。

我的 XML 文件:

        import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

import com.google.common.io.Resources;

import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.nio.charset.Charset;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class ModifyXMLFile {

public static void main(String args[]) {

try {
// Point the file directory path here
String directory = "C:\\Users\\n444479\\Desktop\\SA";
int test = new File("C:\\Users\\n444479\\Desktop\\SA").listFiles().length;
File[] files = new File(directory).listFiles();

// Loop the file to run all the XML files
for (int j = 0; j < test; j++) {
System.out.println(files[j]);

String filepathext = files[j].toString();

DocumentBuilderFactory docFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepathext);

/*
// XML file update starts here

// 1.Add the attribute element with value between the two XML
// Child elements



NodeList nodes = doc.getElementsByTagName("dummySegmentOne");
Text a = doc.createTextNode("value"); Element p =
doc.createElement("newNode"); p.appendChild(a);
nodes.item(0).getParentNode().insertBefore(p, nodes.item(0));


// 2.Add the attribute element without value between the two XML
// Child elements


NodeList nodesa =
doc.getElementsByTagName("customerLevelRegDocs"); Element q =
doc.createElement("dummySegmentOne");
nodesa.item(0).getParentNode().insertBefore(q,
nodesa.item(0));


// 3.Rename the element in parent and child both using the JAXP
// Parser
*/
// XSLT File:

String xsltResource = "C:\\Users\\n444479\\Desktop\\AB\\test.xml";

StringWriter xmlResultResource = new StringWriter();

Transformer xmlTransformer = TransformerFactory.newInstance().newTransformer(
new StreamSource(new File(xsltResource)));
xmlTransformer.transform(new StreamSource(new File(filepathext)),new StreamResult(xmlResultResource));

// XML file update end here

// write the content into XML file
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new String(filepathext));
transformer.transform(source, result);
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
// Successful output once get it "Done"
String output = xmlResultResource.getBuffer().toString();
// Writing the transformed XML to a file
FileWriter fileWriter = new FileWriter(filepathext);
fileWriter.write(output);
fileWriter.close();

System.out.println("Done");

}
}
// Exception handling
catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
}
}

}

程序执行后,字符串会正确附加,但 XML 文件对齐方式会发生变化。

我得到的输出如下

<?xml version="1.0" encoding="UTF-8"?>{% from lxml import etree %}{% from StringIO import StringIO %}{% set tree = parse_xml(request_text) %}{% set namespaces = {'soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',  'wbs': 'http://xml.ama.com/ws/2009/01/WBS_Session-2.0.xsd'}%}<soap:Envelope xmlns:xalan="http://xml.apache.org/xalan" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><Session><SessionId>{{tree.xpath('//soapenv:Header/wbs:Session/wbs:SessionId', namespaces=namespaces)[0].text}}</SessionId><SequenceNumber>{{int(tree.xpath('//soapenv:Header/wbs:Session/wbs:SequenceNumber', namespaces=namespaces)[0].text)+1}}</SequenceNumber><SecurityToken>{{tree.xpath('//soapenv:Header/wbs:Session/wbs:SecurityToken', namespaces=namespaces)[0].text}}</SecurityToken></Session></soap:Header><soap:Body><reRoot><reNode> world</reNode></reRoot></soap:Body></soap:Envelope>

为什么文件没有被附加

最佳答案

原因是DataInputStream.readLine丢弃换行符。因此,您必须自己附加它。

此外:考虑到生成的 XML 是不正确的,因为原来的 XML header 包含在一个节点中。 header (如果存在)必须始终位于根节点之前。

要将您的输入 XML 正确转换为 SOAP,我建议您使用两种替代方法:

  • 要么通过 XSL 样式表对其进行转换。
  • 或者使用 DOM 构建生成的 XML,并将源 XML 作为一个子节点包含在内。然后,在序列化整个文档时,您可以指定缩进参数。

更新

我向您推荐这个 XSL:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" version="1.0" encoding="UTF-8"/>

<xsl:strip-space elements="*"/>

<xsl:template match="/">{% from lxml import etree %}{% from StringIO import StringIO %}{% set tree = parse_xml(request_text) %}{% set namespaces = {'soapenv': 'http://schemas.xmlsoap.org/soap/envelope/', 'wbs': 'http://xml.ama.com/ws/2009/01/WBS_Session-2.0.xsd'}%}<soap:Envelope xmlns:xalan="http://xml.apache.org/xalan" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Session>
<SessionId>{{tree.xpath('//soapenv:Header/wbs:Session/wbs:SessionId', namespaces=namespaces)[0].text}}</SessionId>
<SequenceNumber>{{int(tree.xpath('//soapenv:Header/wbs:Session/wbs:SequenceNumber', namespaces=namespaces)[0].text)+1}}</SequenceNumber>
<SecurityToken>{{tree.xpath('//soapenv:Header/wbs:Session/wbs:SecurityToken', namespaces=namespaces)[0].text}}</SecurityToken>
</Session>
</soap:Header>
<soap:Body><xsl:copy-of select="."/>
</soap:Body>
</soap:Envelope>
</xsl:template>

</xsl:stylesheet>

换句话说:它创建一个具有固定格式的 SOAP 消息,并将输入 xml 设置为 <soap:Body> 的内容。节点。

以及转换代码:

private static void transform(org.w3c.dom.Document doc, java.io.InputStream inputXsl, java.io.OutputStream out)
throws java.io.IOException,
javax.xml.transform.TransformerConfigurationException,
javax.xml.transform.TransformerException
{
javax.xml.transform.Templates templates=javax.xml.transform.TransformerFactory.newInstance().newTemplates(new javax.xml.transform.stream.StreamSource(inputXsl));
javax.xml.transform.Transformer transformer=templates.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
javax.xml.transform.Result result=new javax.xml.transform.stream.StreamResult(out);
javax.xml.transform.Source source=new javax.xml.transform.dom.DOMSource(doc);
if (doc.getInputEncoding() != null)
{
transformer.setOutputProperty("encoding", doc.getInputEncoding());
}
transformer.transform(source, result);
}

整个结果重新缩进有两个原因:

  • xsl:strip-space在 XSL 中。
  • indentindent-amount转换中的属性。

关于java - 为什么在使用 java 将字符串追加到文件的开头和结尾后,xml 文件没有正确对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39294618/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com