Would like to output xml file as in body from python using lxml - python-3.x

Would like to output the following at the head of xml
I can find lots on parsing and validating, but not so much on creation/output
I can find some documentation on QName but how do I output
`
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gdml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://service-spi.web.cern.ch/service-spi/app /releases/GDML/schema/gdml.xsd">`

Use QName to create the attribute (noNamespaceSchemaLocation) that is bound to the http://www.w3.org/2001/XMLSchema-instance namespace.
from lxml.etree import QName, Element, tostring
qname = QName("http://www.w3.org/2001/XMLSchema-instance", "noNamespaceSchemaLocation")
attr_dict = {qname: "http://service-spi.web.cern.ch/service-spi/app /releases/GDML/schema/gdml.xsd"}
gdml = Element("gdml", attr_dict)
print(tostring(gdml, encoding="UTF-8", standalone=False).decode())
Output:
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<gdml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://service-spi.web.cern.ch/service-spi/app /releases/GDML/schema/gdml.xsd"/>
The namespace declaration (xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance") is created automatically.

Thanks - I already did it another way
NS = 'http://www.w3.org/2001/XMLSchema-instance'
location_attribute = '{%s}noNameSpaceSchemaLocation' % NS
gdml = ET.Element('gdml',attrib={location_attribute: 'http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd'})
print(gdml.tag)

Related

Python lxml.etree: how to add 'xml:lang="en-US"' as a namespace

I am trying to create a xml whose first element is:
<speak version="1.0"
xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
</speak>
I am able to add the first attributes with...
from lxml.etree import Element, SubElement, QName, tostring
root = Element('speak', version="1.0",
xmlns="http://www.w3.org/2001/10/synthesis")
...but not the namespace xml:lang="en-US". Based on several tuto/question like this and this I tried many solutions but none worked.
For example, I tried this :
class XMLNamespaces:
xml = 'http://www.w3.org/2001/10/synthesis'
root.attrib[QName(XMLNamespaces.xml, 'lang')] = "en-US"
But the ouput is
<speak xmlns:ns0="http://www.w3.org/2001/10/synthesis" version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" ns0:lang="en-US">
How can I create the xml:lang="en-US" of my first xml element?
The special xml: prefix is associated with the http://www.w3.org/XML/1998/namespace URI.
The following code adds xml:lang="en-US" to the root element:
root.attrib[QName("http://www.w3.org/XML/1998/namespace", "lang")] = "en-US"

Read an XML file using node.js xpath xmldom

I'm attempting to select certain parts of an XML document using the node packages XPATH & XMLDOM, but I am getting nothing through for the element values. At a guess it's probably my XPATH definition, but to be honest I've no idea.
The top of my XML looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="define2-0-0.xsl"?>
<ODM
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.cdisc.org/ns/odm/v1.3"
xmlns:def="http://www.cdisc.org/ns/def/v2.0"
ODMVersion="1.3.2"
FileType="Snapshot"
FileOID="StudyNum.ADaM-IG.1.0"
CreationDateTime="2018-02-08T09:40:51">
<Study OID="StudyNum.ADaM-IG.1.0">
<GlobalVariables>
<StudyName>StudyNum</StudyName>
<StudyDescription>Study Description</StudyDescription>
<ProtocolName>StudyName_PRCL_StudyNum</ProtocolName>
</GlobalVariables>
<MetaDataVersion OID="MDV.StudyNum.ADaM-IG.1.0" Name="Study StudyNum Data Definitions"
Description="Awful Syndrome"
def:DefineVersion="2.0.0"
and my code so far looks like the following:
var xpath = require('xpath'),
dom = require('xmldom').DOMParser,
fs = require('fs');
var xml = fs.readFileSync('./Define/define.xml', 'utf8').toString();
var select = xpath.useNamespaces({"xlink":"http://www.w3.org/1999/xlink", "ODM":"http://www.cdisc.org/ns/odm/v1.3", "def":"http://www.cdisc.org/ns/def/v2.0"});
var doc = new dom().parseFromString(xml)
console.log("test 1 : " + select('//ODM:Study/#OID', doc)[0].nodeValue);
console.log("test 2 : " + select('//ODM:Study/GlobalVariables/StudyName/', doc)[0].nodeValue);
The first test generates the expected result, but I just get an error with 'test 2'. Am I missing the obvious?
Thanks.
You simply forgot that namespaces defined with xmlns="..." on an element are inherited to the child nodes.
So the line xmlns="http://www.cdisc.org/ns/odm/v1.3" in your XML makes all the children having this (an ODM) namespace.
//ODM:Study/ODM:GlobalVariables/ODM:StudyName
Putting that in the whole expression it's
console.log("test 2 : " + select('//ODM:Study/ODM:GlobalVariables/ODM:StudyName', doc)[0].nodeValue);

How to get the Structure/Template id by Structure/Template name

I have a requirement that, Need to create JournalArticle with Structure and Template.While creating JournalArticle the method expecting the StructureId and TemplateId but these are generated by Liferay.So by name how can i get Id's of both.
Create and execute a DynamicQuery, like so (just replace Template with Structure to get structures):
DynamicQuery q = DynamicQueryFactoryUtil.forClass(DDMTemplate.class)
.add(PropertyFactoryUtil.forName("name").like("%YOUR NAME%"));
List<DDMTemplate> templates = DDMTemplateLocalServiceUtil.dynamicQuery(q);
You have to use like since the names of the structures/templates are saved like so:
<?xml version='1.0' encoding='UTF-8'?>
<root available-locales="de_DE" default-locale="de_DE">
<Name language-id="de_DE">YOUR NAME</Name>
</root>
There can be different names for different locales.
You can get StructureId (called DDMStructure) with this code
long classNameIdJournalArticle = ClassNameLocalServiceUtil.getClassNameId(JournalArticle.class);
DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(groupId, classNameIdJournalArticle, "myDDMStructureName");
And TemplateId (called DDMTemplate) with this code
DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(groupId, classNameIdDDMStructure, "ddmTemplateName");

Type conversion error while using Linq to XML

I have created a sample XML. And trying to Read by using LINQ
here is the code:
XElement root = XElement.Load("C:\\............\\TestData.xml");
IEnumerable<Xelement> address = from tt in root.Elements("Test")
select tt;
I am getting compile time error at select statement :
Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>'
to 'System.Collections.Generic.IEnumerable<EvalTest.Xelement>'.
An explicit conversion exists (are you missing a cast?)
XML:
<?xml version="1.0" encoding="utf-8" ?>
<TestData>
<Test Method="1">
<ID>1</ID>
<Submitter> Ritvij</Submitter>
<Date>11/5/2013 2:51:57 PM </Date>
</Test>
<Test Method="2">
<ID>1</ID>
<Submitter> Ritvij</Submitter>
<Date>11/5/2013 2:51:57 PM </Date>
</Test>
</TestData>
root.Elements returns an IEnumerable<XElement> (with a capital "E"), but you're trying to assign it to IEnumerable<Xelement> (lower case "e").
Either modify your code to use XElement or use var:
IEnumerable<XElement> address = from tt in root.Elements("Test") select tt;
var address = from tt in root.Elements("Test") select tt;

Where does xmlns:tns come from when using schemagen

We are using schemagen to create an XSD from some annotated POJOs.
Here is our ant target
<target name="generate-xsd" depends="compile">
<taskdef name="schemagen" classname="com.sun.tools.jxc.SchemaGenTask"
classpathref="xjc.classpath"/>
<schemagen srcdir="src" destdir="generated" includeantruntime="false">
<include name="com/acme/exam/delivery/records/**"/>
<schema namespace="http://www.acme.com/deliverylog"
file="deliverylog.xsd"/>
<schema namespace="" file="supplemental.xsd"/>
</schemagen>
</target>
This is generating
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://www.acme.com/deliverylog"
xmlns:tns="http://www.acme.com/deliverylog"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Where does the tns namespace come from and what does it signify?
That infomration comes from the package level annotation #XmlSchema which can be found in the package-info class. See below for an example.
package-info
#XmlSchema(
namespace = "http://www.acme.com/deliverylo",
elementFormDefault = XmlNsForm.QUALIFIED)
package example;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Sample XML
elementFormDefault specifies which elements should be namespace qualified (true = all, false = only global elements), and targetNamespace defines what the namespace is.
<foo xmlns="http://www.acme.com/deliverylog">
<bar>Hello World</bar>
</foo>
For More Information
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html

Resources