I have an xml/mathml fragment in string like <msup><mn>2</mn><mn>6</mn></msup><mo>+</mo><msup><mn>2</mn><mn>7</mn></msup>
I want to replace an existing xml node with this string. I tried
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuild = docFactory.newDocumentBuilder();
Document doc = docBuild.parse(is); //is ==> Inputstream
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new Namespace());
XPathExpression expr = xpath.compile(xPath); //xPath ==>XPath of parent node where the above is to be appended
Node node = (Node) expr.evaluate(doc, XPathConstants.NODE);
if (node.getChildNodes().item(0).getNodeName().equals("mml:math")) {
node.removeChild((node.getChildNodes().item(0)));
Element s= doc.createElement("mml:math");
s.setNodeValue("<msup><mn>2</mn><mn>6</mn></msup><mo>+</mo><msup><mn>2</mn><mn>7</mn></msup>");
node.appendChild(s);
}
Instead of using s.setNodeValue(), I used s.setTextContent() which fixed my problem.
Related
I am trying to find the NodeList of the nodes containing any number of certain attributes in the XML file.
I can do the following and get the NodeList
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document schDoc = db.newDocument();
InputStream schStream = new ByteArrayInputStream(sch.xml);
schDoc = db.parse(schStream)
schDoc.getDocumentElement().normalize();
XPath xpath1 = XPathFactory.newInstance().newXpath();
String expAttStr = "descendant-or-self::*[contains(#Name,'total_amt')]";
XPathExpression exprForTotalAmt = xpath1.compile(expAttStr);
NodeList totalAmtNodeList = (NodeList) exprForTotalAmt.evaluate(schDoc,XPathConstants.NODESET);
This is good.. But how can I loop and change the value of the attribute name. I tried the following and didn't work:
List<String> listOfItems= Arrays.asList("total_amt", "purchase_amt", "sales_amt");
long count = listOfItems.stream.distinct().count();
for(int i = 0; i<count; i++){
String expAttStr = "descendant-or-self::*[contains(#Name,listOfItems.get(i)]";
XPathExpression exprForTotalAmt = xpath1.compile(expAttStr);
NodeList totalAmtNodeList = (NodeList) exprForTotalAmt.evaluate(schDoc,XPathConstants.NODESET);
//some tasks
}
Would really appreciate it if anyone can point me in the right direction. Thanks.
I am trying to extract node value with multiple namespaces in java but not succeed. The xml file is like:
<ns26:start xmlns:ns26="http://www.tektronix.com/iris/isa/capture/start"
xmlns:ns31="http://www.tektronix.com/iris/isa/filters"
xmlns:ns13="http://www.tektronix.com/iris/isa/monitoredObjects"
xmlns:ns6="http://www.tektronix.com/iris/isa"
xmlns:ns10="http://www.tektronix.com/iris/isa/monNodeObjects"
xmlns:ns7="http://www.tektronix.com/iris/isa/capture/monitoredElements"
xmlns:ns11="http://www.tektronix.com/iris/isa/pointcodes"
xmlns:ns8="http://www.tektronix.com/iris/isa/capture/captureSession"
xmlns:ns2="http://www.tektronix.com/iris/isa/sessionSaveInfo"
xmlns:ns4="http://www.tektronix.com/iris/isa/customData"
xmlns:ns3="http://www.tektronix.com/iris/isa/manifest">
<ns6:Id>LAB:11300/isaclient;440</ns6:Id>
</ns26:start>
I want to extract Id with xpath local-name(). Expression like //*[local-name()='start']/*[local-name()='Id'] but didn't get any matched node. Please help to find issue here. Thanks
Add the java code here:
public static List<String> getXPathValueNamespace(String xml, String expression throws ParserConfigurationException, SAXException, IOException, XPathExpressionException
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc = null;
List<String> list = new ArrayList<String>();
builder = factory.newDocumentBuilder();
InputSource source = new InputSource(new StringReader(xml));
doc = builder.parse(source);
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
XPathExpression expr = xpath.compile(expression);
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++)
list.add(nodes.item(i).getNodeValue());
return list;
}
The expression //*[local-name()='start']/*[local-name()='Id'] works and for the example document one node should be contained in the result node list.
But you should use nodes.item(i).getTextContent() to retrieve the node content, since getNodeValue() returns null for element nodes.
Can we search a element by id in xml file using dom parser, for example :
<root>
<context id="one">
<entity>
<identifier>new one</identifier>
</entity>
</context>
<context id="two">
<entity>
<identifier>second one</identifier>
</entity>
</context>
</root>
I want a node with id = "one", my code
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(new File("filename.xml"));
Element ele = document.getElementById("one");
return null,
is there any other way?
From the documentation for Document.getElementById
Note: Attributes with the name "ID" or "id" are not of type ID unless so defined.
The problem is the Document doesn't know that an attribute called id is an identifier unless you tell it. You need to set a schema on the DocumentBuilderFactory before you call newDocumentBuilder. That way the DocumentBuilder will be aware of the element types.
In the schema you will need something like this in the appropriate place:
<xs:attribute name="id" type="xs:ID"/>
You could use the javax.xml.xpath APIs in the JDK/JRE to find the element by XPath.
Example
import java.io.File;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
public class Demo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(new File("filename.xml"));
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
Element element = (Element) xpath.evaluate("//*[#id='one']", document, XPathConstants.NODE);
}
}
You could instead use a third party library like Jsoup that does the job rather quite well.
File input = new File("/tmp/input.xml");
Document doc = Jsoup.parse(input, "UTF-8", "test");
And then you could use something like this:
doc.select("context#id=one")
Does that answer your question?
try and use XML - Xpath expression it is very easy
File fXmlFile = new File("filePath");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
String expression;
Node node;
// 1. elements with id '1'
expression = "//context[#id='one']";
node = (Node ) xpath.evaluate(expression, doc, XPathConstants.NODE);
How do you parse the same name tag in xml using dom parser java?
I have the following xml file that I would like to parse using the dom parser in java.
<?xml version="1.0"?>
<GameWorld>
<player>
<playerID>1</playerID>
<inventory>
<item>cards</item>
<item>notes</item>
<item>dice</item>
</inventory>
<position>50 50 10 60</position>
<room>offices</room>
</player>
<player>
<playerID>2</playerID>
<inventory>
<item>notes</item>
<item>dice</item>
<item>cards</item>
</inventory>
<position>10 10 10</position>
<room>security room</room>
</player>
</GameWorld>
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(f);
Element root = doc.getDocumentElement();
NodeList nodeList = doc.getElementsByTagName("player");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
// do your stuff
}
but I'd rather suggest to use XPath
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(<uri_as_string>);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("/GameWorld/player");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
In XML file a Parent tag has multiple child tag, with content inside.
I need the Parent tag info only,
how to get that:
i.e.,
<main>**Name**
<names>**Harish**</names>
<names2>**Mathi**</names>
</main>
Here i need only "Name". I no need "Harish","Mathi"...
in this case what i have to include in JAVA code...
You can do using XPath:
main/text()
UPDATE:
Example:
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("sample.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("main/text()");
Object result = expr.evaluate(doc, XPathConstants.STRING);
System.out.println(result.toString());
OUTPUT:
**Name**