英文:
How to modify an xml document and return it as a string in java?
问题
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.filter.ElementFilter;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Iterator;
public String removeIds(String xmlString) {
Document doc = null;
SAXBuilder saxBuilder = new SAXBuilder();
try {
doc = saxBuilder.build(new StringReader(xmlString));
} catch (JDOMException je) {
je.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
}
Element rootNode = doc.getRootElement();
Iterator<Element> rootChildren = rootNode.getDescendants(new ElementFilter("Person"));
for (Element person : rootChildren) {
for (Element identity : person.getChildren("Identity")) {
identity.removeChildren("id");
}
}
try {
XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
StringWriter writer = new StringWriter();
xmlOutputter.output(doc, writer);
String output = writer.getBuffer().toString();
return output;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Note: The provided code snippet was modified to correct certain errors and to make it more functional. The provided code should be used in the context of a Java project with the JDOM library imported and configured correctly. Make sure you have the necessary libraries and dependencies set up for your project before using this code.
英文:
I have this string containing my request xml. I want to delete below "id" tags from this string if they exist and return it back. Removing "Identity" completely will also work, if that can be done.
To be deleted :
<Identity>
<id extension="7865232" aan = "BUH"/>
<code/>
</Identity>
<Identity>
<id extension="88769032" aan = "DIH"/>
<code/>
</Identity>
String XMLString= "<request version ="1.0">
<minMatch>
<val>100</val>
</minMatch>
<paramList>
<payLoad display = "Full" type="F">
</payLoad>
<IQC code = "2">
</IQC>
<Control display="Default" type = "D">
</Control>
<member>
<memCode code = "Active"
</memCode>
<id extension="12345" aan="ACC"></id>
<id extension="54321" aan="REQ"></id>
<id extension="554376" aan="PDR"></id>
<id extension="66321" aan="NJQ"></id>
<addr use = "H">
<streetLine>123</streetLine>
<city>POLIS</city>
<state>NY</state>
<postalCode>44321</postalCode>
</addr>
<telecom value = "5543213">
</telecom>
<Person>
<name>
<given>JOHN</given>
<family>BILL</family>
</name>
<GenderCode code ="M" display="Male">
</GenderCode>
<birthime vaue="19651002">
</birthime>
<Identity>
<id extensio="7865232" aan = "BUH"/>
<code/>
</Identity>
<Identity>
<id extensio="88769032" aan = "DIH"/>
<code/>
</Identity>
</Person>
</member>
----
---
</request>"
I am using below code to achieve the same but it's not working and giving me The constructor DOMSource(Document) is undefined. I tired converting document into a byte Array but that's also not working.Is there any way i can simply do this in Java 1.8. Any other approach is also welcome.
Please suggest.Thank you!
public void removeIds(String xmlString){
Document doc = null;
SAXBuilder saxbuilder = new SAXBuilder();
try{
doc = saxbuilder.build(new StringReader(xmlString));
}catch(JDOMException je){
je.printStackTrace();
}catch(IOException ie){
ie.printStackTrace();
}
Element rootNode = doc.getRootElement();
IteratorIterable<Element> rootChildren=rootNode.getDescendants(new ElementFilter("Person"));
for(Element Person:rootChildren){
for(Element Identity:Person.getChildren("Identity")){
((Element) doc.getRootElement.getDescendants(new ElementFilter("Identity"))).removeChild("id");
}
}
try{
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer;
transformer = tf.newTransformer();
// transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(doc), new StreamResult(writer));
String output = writer.getBuffer().toString();
return output;
} catch (TransformerException e) {
e.printStackTrace();
}
}
答案1
得分: 2
由于您已经调用了一个转换,所以在XSLT中完成所有工作要比在低级DOM操作中瞎弄要简单得多。
如果您使用XSLT 3.0(Saxon),样式表如下:
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes" encoding="utf-8"/>
<xsl:template match="id"/>
</xsl:transform>
您可以将输入提供给此转换,方法是 new StreamSource(new StringReader(xmlString))
— 无需首先构建DOM。
这也可以在XSLT 1.0中完成(例如,使用捆绑在JDK中的Xalan),但会有点冗长。
英文:
Since you're invoking a transformation anyway, it's much simpler to do all the work in XSLT rather than fiddle about with low-level DOM manipulation.
If you use XSLT 3.0 (Saxon) then the stylesheet is simply
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes" encoding="utf-8"/>
<xsl:template match="id"/>
</xsl:transform>
You can supply the input to this transformation as new StreamSource(new StringReader(xmlString))
-- there's no need to construct a DOM first.
It can be done in XSLT 1.0 too (i.e. with Xalan, which comes bundled with the JDK), but is a bit more verbose.
答案2
得分: 1
以下是使用XPath API的解决方案。在这个例子中,所有位于元素“Identity”内部的元素“id”都被移除(XPath表达式“//Identity/id”)。如果您想要移除所有的id元素,请将表达式更改为“//id”。
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
// XML序列化的函数
public static String serialize(Document document) {
removeWhitespaces(document.getDocumentElement());
try (StringWriter writer = new StringWriter()) {
StreamResult result = new StreamResult(writer);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(document), result);
return writer.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 用于去除空白的辅助函数
public static void removeWhitespaces(Element element) {
NodeList children = element.getChildNodes();
for (int i = children.getLength() - 1; i >= 0; i--) {
Node child = children.item(i);
if (child instanceof Text && ((Text) child).getData().trim().isEmpty()) {
element.removeChild(child);
} else if (child instanceof Element) {
removeWhitespaces((Element) child);
}
}
}
// 主要代码
// 解析XML
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(xml)));
// 查找id元素
XPathExpression xpath = XPathFactory.newInstance().newXPath().compile("//Identity/id");
NodeList nodes = (NodeList) xpath.evaluate(doc, XPathConstants.NODESET);
// 移除找到的元素
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
node.getParentNode().removeChild(node);
}
// 序列化并输出文档
String result = serialize(doc);
System.out.println(result);
英文:
Here is solution using XPath API. In this example all elements "id" inside elements "Identity" are removed (XPath expression "//Identity/id"). If you want to remove all id elements, change it to "//id".
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
// function for XML serialization
public static String serialize(Document document) {
removeWhitespaces(document.getDocumentElement());
try (StringWriter writer = new StringWriter()) {
StreamResult result = new StreamResult(writer);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.transform(new DOMSource(document), result);
return writer.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// helper function for stripping whitespaces
public static void removeWhitespaces(Element element) {
NodeList children = element.getChildNodes();
for (int i = children.getLength() - 1; i >= 0; i--) {
Node child = children.item(i);
if (child instanceof Text
&& ((Text) child).getData().trim().isEmpty()) {
element.removeChild(child);
} else if (child instanceof Element) {
removeWhitespaces((Element) child);
}
}
}
Main code:
// parse XML
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(xml)));
// find id elements
XPathExpression xpath = XPathFactory.newInstance().newXPath().compile("//Identity/id");
NodeList nodes = (NodeList)xpath.evaluate(doc, XPathConstants.NODESET);
// remove found elements
for(int i = 0; i < nodes.getLength(); i ++) {
Node node = nodes.item(i);
node.getParentNode().removeChild(node);
}
// serialize and output document
String result = serialize(doc);
System.out.println(result);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论