Writing an XML in Matlab: How to add reference to DTD? - java

I'm trying to write an XML file using Matlab and I need to specify a DOCTYPE DTD at the header, but I haven't found any method for this in the Matlab documentation or questions related. Every question involving a DTD reference is about how to read an XML into Matlab.
What I am able to do now is an XML file of the type
<?xml version="1.0"?>
<root>
<child>
Hello world!
</child>
</root>
with the code
docNode = com.mathworks.xml.XMLUtils.createDocument('root');
root = docNode.getDocumentElement;
child = docNode.createElement('child');
child.appendChild(docNode.createTextNode('Hello World!'));
root.appendChild(child);
xmlwrite(docNode)
However, I need the file to include a DTD reference:
<?xml version="1.0"?>
<!DOCTYPE root SYSTEM "root.dtd" []>
<root>
<child>
Hello world!
</child>
</root>
Is there any function in com.mathworks.xml.XMLUtils for this? Or will I have to open the generated XML and manually insert the DTD reference?

You can stay with using the org.w3c.dom package: you can use the createDocumentType method of DOMImplementation.
domImpl = docNode.getImplementation();
doctype = domImpl.createDocumentType('root', 'SYSTEM', 'root.dtd');
With this update the full sample code is:
docNode = com.mathworks.xml.XMLUtils.createDocument('root');
domImpl = docNode.getImplementation();
doctype = domImpl.createDocumentType('root', 'SYSTEM', 'root.dtd');
docNode.appendChild(doctype);
root = docNode.getDocumentElement;
child = docNode.createElement('child');
child.appendChild(docNode.createTextNode('Hello World!'));
root.appendChild(child);
xmlwrite(docNode)
Output
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root PUBLIC "SYSTEM" "root.dtd">
<root>
<child>Hello World!</child>
</root>

Related

How to merge multple XML files and make proper namespaces in result XML

I have few XMLs needs to be merged and create a new xml. How i can extract the xml namespaces from the xmls and use it for resulting xml.
xml1
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root1 xmlns:xlink="ABC/xlink" xmlns:xsi="XYZ/instance">
<tag1>123</tag1>
</root1>
xml2
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root2 xmlns:xlink2="EFG/xlink2" xmlns:xsi="XYZ/instance">
<tag2>321</tag2>
</root2>
expected result xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root xmlns:xlink="ABC/xlink" xmlns:xsi="XYZ/instance" xmlns:xlink2="EFG/xlink2">
<tag1>123</tag1>
<tag2>321</tag2>
</root>
Currently i am trying like below
Pattern pattern = Pattern.compile("xmlns[\\s\\S]*?>");
Matcher matcher = pattern.matcher(stringxml);
while(matcher.find()){
//storing the namespace.
}
Trying to do String manipulation to create the proper xml namespace. There are quite a few string operations happening to handle the namespace properly like need to avoid the duplicate namespace if its defined in both xmls. Is there any other better way to do it ?

how to compare prefixed with no prefix xml documents in xmlunit to get similar result

xmlnit does not recognize the following two xml "identical" (except one has defined namespace) documents to be similar:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:message xmlns:ns3="https://www.bookmarks.dev/xml/bookmarks">
<ns3:bookmarks>
<ns3:bookmark>
<ns3:name>Bookmarks and Snippets Manager</ns3:name>
<ns3:url>https://www.bookmarks.dev</ns3:url>
</ns3:bookmark>
</ns3:bookmarks>
</ns3:message>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<message>
<bookmarks>
<bookmark>
<name>Bookmarks and Snippets Manager</name>
<url>https://www.bookmarks.dev</url>
</bookmark>
</bookmarks>
</message>
The failing unit test comparing the two:
#Test
void givenSameMessageOneWithoutNamespace_shouldBeSimilar() {
ClassLoader classLoader = getClass().getClassLoader();
final var withNamespaceInput =
Input.from(
new File(classLoader.getResource("with-namespace.xml").getFile()));
final var noNamespaceInput =
Input.from(
new File(
classLoader
.getResource("no-namespace.xml")
.getFile()));
final Diff documentDiff =
DiffBuilder.compare(withNamespaceInput)
.withTest(noNamespaceInput)
.checkForSimilar()
.build();
assertThat(documentDiff.hasDifferences()).isFalse();
}
The differences come in the form Expected namespace uri 'null' but was 'https://www.bookmarks.dev/xml/bookmarks' - comparing <message...> at /message[1] to <ns3:message...> at /message[1] (DIFFERENT)...
Any ideas how can I configure the comparator to ignore the missing prefix in the second document?
My problem was that when generating the no-namespace document I had no default namespace defined in the root element. Adding it solves the problem and xmlunit recognizes them as similar:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<message xmlns="https://www.bookmarks.dev/xml/bookmarks">
<bookmarks>
<bookmark>
<name>Bookmarks and Snippets Manager</name>
<url>https://www.bookmarks.dev</url>
</bookmark>
</bookmarks>
</message>

How to define XML entities in Java using Dom4J?

I'm trying to add entity declarations to my XML document in Java using Dom4J 2.1.1, but can't figure out how to do so, or if it's even possible. Can anyone help please?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE TEAMS_ASSET_FILE PUBLIC "-//TEAMS//DTD asset and link file//EN" "D:\Apps\data\Tasset.dtd" [
<!ENTITY asset0000001 SYSTEM "Z:\somepath\1234\myfile.pdf">
<!ENTITY asset0000002 SYSTEM "Z:\anotherpath\5678\another.pdf">
]>
<content>
...
</content>
see DocumentType-Interface [https://dom4j.github.io/javadoc/2.1.1/org/dom4j/DocumentType.html]. Get it by using
DocumentType docType = doc.getDocType();
and then add entities as InternalEntityDecl/ExternalEntityDecl with
setExternalDeclarations(java.util.List<Decl> declarations)
or
setInternalDeclarations(java.util.List<Decl> declarations)

Java appending an element to XML document

I am trying to append an element to my xml document so it looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students>
</students>
However, it ends up looking like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students/>
This is the code I am using:
// results is the new XML document I created using DocumentBuilder.newDocument();
Element root = results.createElement("students");
results.appendChild(root);
How come it isn't looking like how I want it to?
Java dom is implemented based on the xml specification, and by definition: An element with no content is said to be empty : https://www.w3.org/TR/REC-xml/#sec-starttags.

How to Add Namespace to XML in java?

I have below xml. Namespace is missing in the below xml.
<?xml version="1.0" encoding="UTF-8"?>
<policy>
<num-drivers>123</num-drivers>
<risk-policy-ind>false</risk-policy-ind>
<premium-amt>23.00</premium-amt>
</policy>
Looking for java code to take the above xml as input and add namespace (xmlns) element to it? The expected output xml is as below:
<?xml version="1.0" encoding="UTF-8"?>
<policy xmlns="http://aaa.bbb.com">
<num-drivers>123</num-drivers>
<risk-policy-ind>false</risk-policy-ind>
<premium-amt>23.00</premium-amt>
</policy>
First of all, in the above xml, risk-policy-ind tag is not properly closed. In XML all tags are custom tags, they should close. Moreover,in xml, tags are performed without namespace.
If u just want to add xmlns attribute to policy tag, create policy element using w3c.dom.Element and set attribute using setAttribute function

Categories

Resources