Task 829: .XDM File Format
Task 829: .XDM File Format
File Format Specifications for .XDM
The .XDM file format is used by Oracle BI Publisher as a data model file. It is an XML-based format that defines data sources, structures, parameters, and other elements for generating reports. The structure is defined by an XML schema with a root element , including namespaces for Oracle's XML Publisher and W3C XMLSchema. The format allows for defining SQL queries, data structures, and output configurations.
- List of all the properties of this file format intrinsic to its file system:
- Version (attribute on )
- Default Data Source Reference (attribute on )
- Data Properties:
- include_parameters
- include_null_Element
- include_rowsettag
- xml_tag_case
- Data Sets:
- Name
- Type (e.g., complex)
- SQL (with dataSourceRef and CDATA containing the query)
- Output:
- rootName
- uniqueRowName
- nodeList (name)
- dataStructure (tagName)
- Group (name, label, source)
- Element (name, value, label, dataType, breakOrder, fieldOrder)
- Event Triggers
- Lexicals
- Value Sets
- Parameters
- Bursting
- Display:
- Layouts (layout with name, left, top)
- Group Links
- Two direct download links for files of format .XDM:
I was unable to find public direct download links for .XDM files. However, sample .XDM files can be generated or downloaded from Oracle BI Publisher tools, and examples can be extracted from .XDMZ archives available in Oracle's sample code repositories (e.g., from https://www.oracle.com/downloads/samplecode/bipublisher-samplecode-downloads.html). For demonstration, here's a sample XML content that can be saved as a .xdm file:
<?xml version = '1.0' encoding = 'utf-8'?>
<dataModel xmlns="http://xmlns.oracle.com/oxp/xmlp" version="2.0" xmlns:xdm="http://xmlns.oracle.com/oxp/xmlp" xmlns:xsd="http://www.w3.org/2001/XMLSchema" defaultDataSourceRef="demo">
<dataProperties>
<property name="include_parameters" value="true"/>
<property name="include_null_Element" value="false"/>
<property name="include_rowsettag" value="false"/>
<property name="xml_tag_case" value="upper"/>
</dataProperties>
<dataSets>
<dataSet name="asd" type="complex">
<sql dataSourceRef="ApplicationDB_APP">
<![CDATA[select * from table]]>
</sql>
</dataSet>
</dataSets>
<output rootName="DATA_DS" uniqueRowName="false">
<nodeList name="data-structure">
<dataStructure tagName="DATA_DS">
<group name="G_1" label="G_1" source="asd">
<element name="ENTITY_ID" value="ENTITY_ID" label="ENTITY_ID" dataType="xsd:double" breakOrder="" fieldOrder="1"/>
<element name="ENTITY_NUMBER" value="ENTITY_NUMBER" label="ENTITY_NUMBER" dataType="xsd:string" breakOrder="" fieldOrder="2"/>
</group>
</dataStructure>
</nodeList>
</output>
<eventTriggers/>
<lexicals/>
<valueSets/>
<parameters/>
<bursting/>
<display>
<layouts>
<layout name="asd" left="280px" top="0px"/>
<layout name="DATA_DS" left="0px" top="32px"/>
</layouts>
<groupLinks/>
</display>
</dataModel>- Ghost blog embedded HTML JavaScript for drag and drop .XDM file to dump properties to screen:
- Python class for opening, decoding, reading, writing, and printing .XDM properties:
import xml.etree.ElementTree as ET
from xml.dom.minidom import parseString
class XDMFile:
def __init__(self, filepath):
self.filepath = filepath
self.tree = None
self.root = None
self.properties = {}
def read(self):
self.tree = ET.parse(self.filepath)
self.root = self.tree.getroot()
self._extract_properties()
def _extract_properties(self):
self.properties['version'] = self.root.attrib.get('version')
self.properties['defaultDataSourceRef'] = self.root.attrib.get('defaultDataSourceRef')
data_properties = self.root.find('.//dataProperties', namespaces=self.root.nsmap)
if data_properties is not None:
self.properties['dataProperties'] = [
{'name': prop.attrib['name'], 'value': prop.attrib['value']}
for prop in data_properties.findall('property', namespaces=self.root.nsmap)
]
data_sets = self.root.find('.//dataSets', namespaces=self.root.nsmap)
if data_sets is not None:
self.properties['dataSets'] = [
{
'name': ds.attrib['name'],
'type': ds.attrib['type'],
'sql': ds.find('sql', namespaces=self.root.nsmap).text.strip() if ds.find('sql', namespaces=self.root.nsmap) is not None else None,
'dataSourceRef': ds.find('sql', namespaces=self.root.nsmap).attrib.get('dataSourceRef') if ds.find('sql', namespaces=self.root.nsmap) is not None else None
}
for ds in data_sets.findall('dataSet', namespaces=self.root.nsmap)
]
output = self.root.find('.//output', namespaces=self.root.nsmap)
if output is not None:
self.properties['output'] = {
'rootName': output.attrib['rootName'],
'uniqueRowName': output.attrib['uniqueRowName']
}
data_structure = output.find('.//dataStructure', namespaces=self.root.nsmap)
if data_structure is not None:
self.properties['output']['tagName'] = data_structure.attrib['tagName']
self.properties['output']['groups'] = [
{
'name': g.attrib['name'],
'label': g.attrib['label'],
'source': g.attrib['source'],
'elements': [
{
'name': e.attrib['name'],
'value': e.attrib['value'],
'label': e.attrib['label'],
'dataType': e.attrib['dataType'],
'breakOrder': e.attrib['breakOrder'],
'fieldOrder': e.attrib['fieldOrder']
}
for e in g.findall('element', namespaces=self.root.nsmap)
]
}
for g in data_structure.findall('group', namespaces=self.root.nsmap)
]
self.properties['eventTriggers'] = 'Present' if self.root.find('.//eventTriggers', namespaces=self.root.nsmap) is not None else 'Absent'
self.properties['lexicals'] = 'Present' if self.root.find('.//lexicals', namespaces=self.root.nsmap) is not None else 'Absent'
self.properties['valueSets'] = 'Present' if self.root.find('.//valueSets', namespaces=self.root.nsmap) is not None else 'Absent'
self.properties['parameters'] = 'Present' if self.root.find('.//parameters', namespaces=self.root.nsmap) is not None else 'Absent'
self.properties['bursting'] = 'Present' if self.root.find('.//bursting', namespaces=self.root.nsmap) is not None else 'Absent'
display = self.root.find('.//display', namespaces=self.root.nsmap)
if display is not None:
self.properties['display'] = {
'layouts': [
{
'name': l.attrib['name'],
'left': l.attrib['left'],
'top': l.attrib['top']
}
for l in display.findall('.//layout', namespaces=self.root.nsmap)
],
'groupLinks': 'Present' if display.find('groupLinks', namespaces=self.root.nsmap) is not None else 'Absent'
}
def print_properties(self):
import json
print(json.dumps(self.properties, indent=4))
def write(self, new_filepath=None):
if new_filepath is None:
new_filepath = self.filepath
xml_str = ET.tostring(self.root, encoding='utf-8', method='xml')
dom = parseString(xml_str)
with open(new_filepath, 'w') as f:
f.write(dom.toprettyxml(indent=' '))
# Example usage:
# xdm = XDMFile('example.xdm')
# xdm.read()
# xdm.print_properties()
# xdm.write('new.xdm')
- Java class for opening, decoding, reading, writing, and printing .XDM properties:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
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 java.io.File;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
public class XDMFile {
private String filepath;
private Document doc;
private Map<String, Object> properties = new HashMap<>();
public XDMFile(String filepath) {
this.filepath = filepath;
}
public void read() throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(new File(filepath));
extractProperties();
}
private void extractProperties() {
Element root = doc.getDocumentElement();
properties.put("version", root.getAttribute("version"));
properties.put("defaultDataSourceRef", root.getAttribute("defaultDataSourceRef"));
NodeList dataProps = root.getElementsByTagName("property");
List<Map<String, String>> dataPropertiesList = new ArrayList<>();
for (int i = 0; i < dataProps.getLength(); i++) {
Element prop = (Element) dataProps.item(i);
Map<String, String> map = new HashMap<>();
map.put("name", prop.getAttribute("name"));
map.put("value", prop.getAttribute("value"));
dataPropertiesList.add(map);
}
properties.put("dataProperties", dataPropertiesList);
NodeList dataSets = root.getElementsByTagName("dataSet");
List<Map<String, String>> dataSetsList = new ArrayList<>();
for (int i = 0; i < dataSets.getLength(); i++) {
Element ds = (Element) dataSets.item(i);
Map<String, String> map = new HashMap<>();
map.put("name", ds.getAttribute("name"));
map.put("type", ds.getAttribute("type"));
Element sql = (Element) ds.getElementsByTagName("sql").item(0);
if (sql != null) {
map.put("sql", sql.getTextContent().trim());
map.put("dataSourceRef", sql.getAttribute("dataSourceRef"));
}
dataSetsList.add(map);
}
properties.put("dataSets", dataSetsList);
Element output = (Element) root.getElementsByTagName("output").item(0);
if (output != null) {
Map<String, Object> outputMap = new HashMap<>();
outputMap.put("rootName", output.getAttribute("rootName"));
outputMap.put("uniqueRowName", output.getAttribute("uniqueRowName"));
Element dataStructure = (Element) output.getElementsByTagName("dataStructure").item(0);
if (dataStructure != null) {
outputMap.put("tagName", dataStructure.getAttribute("tagName"));
NodeList groups = dataStructure.getElementsByTagName("group");
List<Map<String, Object>> groupsList = new ArrayList<>();
for (int i = 0; i < groups.getLength(); i++) {
Element g = (Element) groups.item(i);
Map<String, Object> gMap = new HashMap<>();
gMap.put("name", g.getAttribute("name"));
gMap.put("label", g.getAttribute("label"));
gMap.put("source", g.getAttribute("source"));
NodeList elements = g.getElementsByTagName("element");
List<Map<String, String>> elementsList = new ArrayList<>();
for (int j = 0; j < elements.getLength(); j++) {
Element e = (Element) elements.item(j);
Map<String, String> eMap = new HashMap<>();
eMap.put("name", e.getAttribute("name"));
eMap.put("value", e.getAttribute("value"));
eMap.put("label", e.getAttribute("label"));
eMap.put("dataType", e.getAttribute("dataType"));
eMap.put("breakOrder", e.getAttribute("breakOrder"));
eMap.put("fieldOrder", e.getAttribute("fieldOrder"));
elementsList.add(eMap);
}
gMap.put("elements", elementsList);
groupsList.add(gMap);
}
outputMap.put("groups", groupsList);
}
properties.put("output", outputMap);
}
properties.put("eventTriggers", root.getElementsByTagName("eventTriggers").getLength() > 0 ? "Present" : "Absent");
properties.put("lexicals", root.getElementsByTagName("lexicals").getLength() > 0 ? "Present" : "Absent");
properties.put("valueSets", root.getElementsByTagName("valueSets").getLength() > 0 ? "Present" : "Absent");
properties.put("parameters", root.getElementsByTagName("parameters").getLength() > 0 ? "Present" : "Absent");
properties.put("bursting", root.getElementsByTagName("bursting").getLength() > 0 ? "Present" : "Absent");
Element display = (Element) root.getElementsByTagName("display").item(0);
if (display != null) {
Map<String, Object> displayMap = new HashMap<>();
NodeList layouts = display.getElementsByTagName("layout");
List<Map<String, String>> layoutsList = new ArrayList<>();
for (int i = 0; i < layouts.getLength(); i++) {
Element l = (Element) layouts.item(i);
Map<String, String> lMap = new HashMap<>();
lMap.put("name", l.getAttribute("name"));
lMap.put("left", l.getAttribute("left"));
lMap.put("top", l.getAttribute("top"));
layoutsList.add(lMap);
}
displayMap.put("layouts", layoutsList);
displayMap.put("groupLinks", display.getElementsByTagName("groupLinks").getLength() > 0 ? "Present" : "Absent");
properties.put("display", displayMap);
}
}
public void printProperties() {
System.out.println(properties.toString());
}
public void write(String newFilepath) throws Exception {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(doc), new StreamResult(writer));
String output = writer.getBuffer().toString();
// Write to file
transformer.transform(new DOMSource(doc), new StreamResult(new File(newFilepath)));
}
// Example usage:
// public static void main(String[] args) throws Exception {
// XDMFile xdm = new XDMFile("example.xdm");
// xdm.read();
// xdm.printProperties();
// xdm.write("new.xdm");
// }
}
- JavaScript class for opening, decoding, reading, writing, and printing .XDM properties:
class XDMFile {
constructor(filepath) {
this.filepath = filepath;
this.xml = null;
this.properties = {};
}
async read() {
// Assuming node.js with fs
const fs = require('fs');
this.xml = fs.readFileSync(this.filepath, 'utf8');
const parser = new DOMParser();
const doc = parser.parseFromString(this.xml, 'application/xml');
this.extractProperties(doc);
}
extractProperties(doc) {
const root = doc.documentElement;
this.properties.version = root.getAttribute('version');
this.properties.defaultDataSourceRef = root.getAttribute('defaultDataSourceRef');
const dataProperties = doc.querySelector('dataProperties');
if (dataProperties) {
this.properties.dataProperties = Array.from(dataProperties.querySelectorAll('property')).map(p => ({
name: p.getAttribute('name'),
value: p.getAttribute('value')
}));
}
const dataSets = doc.querySelector('dataSets');
if (dataSets) {
this.properties.dataSets = Array.from(dataSets.querySelectorAll('dataSet')).map(ds => ({
name: ds.getAttribute('name'),
type: ds.getAttribute('type'),
sql: ds.querySelector('sql') ? ds.querySelector('sql').textContent.trim() : null,
dataSourceRef: ds.querySelector('sql') ? ds.querySelector('sql').getAttribute('dataSourceRef') : null
}));
}
const output = doc.querySelector('output');
if (output) {
this.properties.output = {
rootName: output.getAttribute('rootName'),
uniqueRowName: output.getAttribute('uniqueRowName')
};
const dataStructure = output.querySelector('dataStructure');
if (dataStructure) {
this.properties.output.tagName = dataStructure.getAttribute('tagName');
this.properties.output.groups = Array.from(dataStructure.querySelectorAll('group')).map(g => ({
name: g.getAttribute('name'),
label: g.getAttribute('label'),
source: g.getAttribute('source'),
elements: Array.from(g.querySelectorAll('element')).map(e => ({
name: e.getAttribute('name'),
value: e.getAttribute('value'),
label: e.getAttribute('label'),
dataType: e.getAttribute('dataType'),
breakOrder: e.getAttribute('breakOrder'),
fieldOrder: e.getAttribute('fieldOrder')
}))
}));
}
}
this.properties.eventTriggers = doc.querySelector('eventTriggers') ? 'Present' : 'Absent';
this.properties.lexicals = doc.querySelector('lexicals') ? 'Present' : 'Absent';
this.properties.valueSets = doc.querySelector('valueSets') ? 'Present' : 'Absent';
this.properties.parameters = doc.querySelector('parameters') ? 'Present' : 'Absent';
this.properties.bursting = doc.querySelector('bursting') ? 'Present' : 'Absent';
const display = doc.querySelector('display');
if (display) {
this.properties.display = {
layouts: Array.from(display.querySelectorAll('layout')).map(l => ({
name: l.getAttribute('name'),
left: l.getAttribute('left'),
top: l.getAttribute('top')
})),
groupLinks: display.querySelector('groupLinks') ? 'Present' : 'Absent'
};
}
}
printProperties() {
console.log(JSON.stringify(this.properties, null, 2));
}
write(newFilepath) {
// Assuming node.js with fs
const fs = require('fs');
const serializer = new XMLSerializer();
const xmlStr = serializer.serializeToString(doc);
fs.writeFileSync(newFilepath, xmlStr);
}
}
// Example usage:
// const xdm = new XDMFile('example.xdm');
// await xdm.read();
// xdm.printProperties();
// xdm.write('new.xdm');
- C "class" (using struct) for opening, decoding, reading, writing, and printing .XDM properties:
Note: C doesn't have classes, so using a struct and functions. This uses libxml2 for XML parsing (assume libxml2 is included).
#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
typedef struct {
char *filepath;
xmlDocPtr doc;
// Properties would be stored in a struct or map, but for simplicity, we'll print directly
} XDMFile;
XDMFile* xdm_new(const char *filepath) {
XDMFile *xdm = malloc(sizeof(XDMFile));
xdm->filepath = strdup(filepath);
xdm->doc = NULL;
return xdm;
}
int xdm_read(XDMFile *xdm) {
xdm->doc = xmlReadFile(xdm->filepath, NULL, 0);
if (xdm->doc == NULL) {
fprintf(stderr, "Failed to parse %s\n", xdm->filepath);
return -1;
}
return 0;
}
void xdm_print_properties(XDMFile *xdm) {
if (xdm->doc == NULL) return;
xmlNode *root = xmlDocGetRootElement(xdm->doc);
if (root == NULL) return;
printf("Version: %s\n", xmlGetProp(root, (xmlChar*)"version"));
printf("Default Data Source Ref: %s\n", xmlGetProp(root, (xmlChar*)"defaultDataSourceRef"));
xmlNode *cur = root->children;
while (cur != NULL) {
if (xmlStrcmp(cur->name, (xmlChar*)"dataProperties") == 0) {
printf("Data Properties:\n");
xmlNode *prop = cur->children;
while (prop != NULL) {
if (xmlStrcmp(prop->name, (xmlChar*)"property") == 0) {
printf(" Name: %s, Value: %s\n", xmlGetProp(prop, (xmlChar*)"name"), xmlGetProp(prop, (xmlChar*)"value"));
}
prop = prop->next;
}
} else if (xmlStrcmp(cur->name, (xmlChar*)"dataSets") == 0) {
printf("Data Sets:\n");
xmlNode *ds = cur->children;
while (ds != NULL) {
if (xmlStrcmp(ds->name, (xmlChar*)"dataSet") == 0) {
printf(" Name: %s, Type: %s\n", xmlGetProp(ds, (xmlChar*)"name"), xmlGetProp(ds, (xmlChar*)"type"));
xmlNode *sql = ds->children;
while (sql != NULL) {
if (xmlStrcmp(sql->name, (xmlChar*)"sql") == 0) {
printf(" SQL: %s\n", xmlNodeGetContent(sql));
printf(" Data Source Ref: %s\n", xmlGetProp(sql, (xmlChar*)"dataSourceRef"));
}
sql = sql->next;
}
}
ds = ds->next;
}
} else if (xmlStrcmp(cur->name, (xmlChar*)"output") == 0) {
printf("Output:\n");
printf(" Root Name: %s, Unique Row Name: %s\n", xmlGetProp(cur, (xmlChar*)"rootName"), xmlGetProp(cur, (xmlChar*)"uniqueRowName"));
xmlNode *nodeList = cur->children;
while (nodeList != NULL) {
if (xmlStrcmp(nodeList->name, (xmlChar*)"nodeList") == 0) {
xmlNode *dataStructure = nodeList->children;
while (dataStructure != NULL) {
if (xmlStrcmp(dataStructure->name, (xmlChar*)"dataStructure") == 0) {
printf(" Tag Name: %s\n", xmlGetProp(dataStructure, (xmlChar*)"tagName"));
xmlNode *group = dataStructure->children;
while (group != NULL) {
if (xmlStrcmp(group->name, (xmlChar*)"group") == 0) {
printf(" Group Name: %s, Label: %s, Source: %s\n", xmlGetProp(group, (xmlChar*)"name"), xmlGetProp(group, (xmlChar*)"label"), xmlGetProp(group, (xmlChar*)"source"));
xmlNode *element = group->children;
while (element != NULL) {
if (xmlStrcmp(element->name, (xmlChar*)"element") == 0) {
printf(" Element Name: %s, Value: %s, Label: %s, DataType: %s, BreakOrder: %s, FieldOrder: %s\n",
xmlGetProp(element, (xmlChar*)"name"), xmlGetProp(element, (xmlChar*)"value"), xmlGetProp(element, (xmlChar*)"label"),
xmlGetProp(element, (xmlChar*)"dataType"), xmlGetProp(element, (xmlChar*)"breakOrder"), xmlGetProp(element, (xmlChar*)"fieldOrder"));
}
element = element->next;
}
}
group = group->next;
}
}
dataStructure = dataStructure->next;
}
}
nodeList = nodeList->next;
}
} else if (xmlStrcmp(cur->name, (xmlChar*)"eventTriggers") == 0) {
printf("Event Triggers: Present\n");
} else if (xmlStrcmp(cur->name, (xmlChar*)"lexicals") == 0) {
printf("Lexicals: Present\n");
} else if (xmlStrcmp(cur->name, (xmlChar*)"valueSets") == 0) {
printf("Value Sets: Present\n");
} else if (xmlStrcmp(cur->name, (xmlChar*)"parameters") == 0) {
printf("Parameters: Present\n");
} else if (xmlStrcmp(cur->name, (xmlChar*)"bursting") == 0) {
printf("Bursting: Present\n");
} else if (xmlStrcmp(cur->name, (xmlChar*)"display") == 0) {
printf("Display:\n");
xmlNode *layouts = cur->children;
while (layouts != NULL) {
if (xmlStrcmp(layouts->name, (xmlChar*)"layouts") == 0) {
xmlNode *layout = layouts->children;
while (layout != NULL) {
if (xmlStrcmp(layout->name, (xmlChar*)"layout") == 0) {
printf(" Layout Name: %s, Left: %s, Top: %s\n", xmlGetProp(layout, (xmlChar*)"name"), xmlGetProp(layout, (xmlChar*)"left"), xmlGetProp(layout, (xmlChar*)"top"));
}
layout = layout->next;
}
} else if (xmlStrcmp(layouts->name, (xmlChar*)"groupLinks") == 0) {
printf(" Group Links: Present\n");
}
layouts = layouts->next;
}
}
cur = cur->next;
}
}
void xdm_write(XDMFile *xdm, const char *new_filepath) {
if (xdm->doc == NULL) return;
xmlSaveFormatFileEnc(new_filepath, xdm->doc, "UTF-8", 1);
}
void xdm_free(XDMFile *xdm) {
xmlFreeDoc(xdm->doc);
free(xdm->filepath);
free(xdm);
}
// Example usage:
// int main() {
// XDMFile *xdm = xdm_new("example.xdm");
// if (xdm_read(xdm) == 0) {
// xdm_print_properties(xdm);
// xdm_write(xdm, "new.xdm");
// }
// xdm_free(xdm);
// return 0;
// }