Monday, February 18, 2008

Use Trang to Generate XML Schema

Trang has been around for a while and is a useful utility for converting between types of XML Schema. In fact, the most recent version for download at the Trang site is version 20030619 (note the date embedded in the version name).

Besides being useful for converting between XML schema definitions, Trang is also useful for generating a new XML schema definition from one or more source XML files. In fact, this use of Trang is the focus of this blog entry. In this blog entry, I will demonstrate how simple it is to apply Trang to generation of W3C XML Schema and DTD definitions from a source XML file.

Oracle provides the highly useful Java OracleXMLQuery class for querying the relational database and provide the query results in XML format. The OracleXMLQuery class provides the setRowsetTag(String) method to specify the Java String to be used as the root tag of the generated XML file containing the query results. Likewise, the OracleXMLQuery.setRowTag(String) method allows one to specify the String label provided for each row element tag in the generated XML file.

The XML below was generated using OracleXMLQuery with the rowset tag specified as "Employees" and the row tag specified as "Employee." The query used to generate this XML was run against the HR schema and is shown next.
SELECT employee_id, first_name, last_name, department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id


The XML generated by OracleXMLQuery is shown next.

employees.xml - XML Generated with OracleXMLQuery
<?xml version = '1.0'?>
<Employees>
<Employee num="1">
<EMPLOYEE_ID>200</EMPLOYEE_ID>
<FIRST_NAME>Jennifer</FIRST_NAME>
<LAST_NAME>Whalen</LAST_NAME>
<DEPARTMENT_NAME>Administration</DEPARTMENT_NAME>
</Employee>
<Employee num="2">
<EMPLOYEE_ID>201</EMPLOYEE_ID>
<FIRST_NAME>Michael</FIRST_NAME>
<LAST_NAME>Hartstein</LAST_NAME>
<DEPARTMENT_NAME>Marketing</DEPARTMENT_NAME>
</Employee>
<Employee num="3">
<EMPLOYEE_ID>202</EMPLOYEE_ID>
<FIRST_NAME>Pat</FIRST_NAME>
<LAST_NAME>Fay</LAST_NAME>
<DEPARTMENT_NAME>Marketing</DEPARTMENT_NAME>
</Employee>
<Employee num="4">
<EMPLOYEE_ID>114</EMPLOYEE_ID>
<FIRST_NAME>Den</FIRST_NAME>
<LAST_NAME>Raphaely</LAST_NAME>
<DEPARTMENT_NAME>Purchasing</DEPARTMENT_NAME>
</Employee>
<Employee num="5">
<EMPLOYEE_ID>119</EMPLOYEE_ID>
<FIRST_NAME>Karen</FIRST_NAME>
<LAST_NAME>Colmenares</LAST_NAME>
<DEPARTMENT_NAME>Purchasing</DEPARTMENT_NAME>
</Employee>
<Employee num="6">
<EMPLOYEE_ID>115</EMPLOYEE_ID>
<FIRST_NAME>Alexander</FIRST_NAME>
<LAST_NAME>Khoo</LAST_NAME>
<DEPARTMENT_NAME>Purchasing</DEPARTMENT_NAME>
</Employee>
<Employee num="7">
<EMPLOYEE_ID>116</EMPLOYEE_ID>
<FIRST_NAME>Shelli</FIRST_NAME>
<LAST_NAME>Baida</LAST_NAME>
<DEPARTMENT_NAME>Purchasing</DEPARTMENT_NAME>
</Employee>
<Employee num="8">
<EMPLOYEE_ID>117</EMPLOYEE_ID>
<FIRST_NAME>Sigal</FIRST_NAME>
<LAST_NAME>Tobias</LAST_NAME>
<DEPARTMENT_NAME>Purchasing</DEPARTMENT_NAME>
</Employee>
<Employee num="9">
<EMPLOYEE_ID>118</EMPLOYEE_ID>
<FIRST_NAME>Guy</FIRST_NAME>
<LAST_NAME>Himuro</LAST_NAME>
<DEPARTMENT_NAME>Purchasing</DEPARTMENT_NAME>
</Employee>
<Employee num="10">
<EMPLOYEE_ID>203</EMPLOYEE_ID>
<FIRST_NAME>Susan</FIRST_NAME>
<LAST_NAME>Mavris</LAST_NAME>
<DEPARTMENT_NAME>Human Resources</DEPARTMENT_NAME>
</Employee>
<Employee num="11">
<EMPLOYEE_ID>198</EMPLOYEE_ID>
<FIRST_NAME>Donald</FIRST_NAME>
<LAST_NAME>OConnell</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="12">
<EMPLOYEE_ID>199</EMPLOYEE_ID>
<FIRST_NAME>Douglas</FIRST_NAME>
<LAST_NAME>Grant</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="13">
<EMPLOYEE_ID>120</EMPLOYEE_ID>
<FIRST_NAME>Matthew</FIRST_NAME>
<LAST_NAME>Weiss</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="14">
<EMPLOYEE_ID>121</EMPLOYEE_ID>
<FIRST_NAME>Adam</FIRST_NAME>
<LAST_NAME>Fripp</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="15">
<EMPLOYEE_ID>122</EMPLOYEE_ID>
<FIRST_NAME>Payam</FIRST_NAME>
<LAST_NAME>Kaufling</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="16">
<EMPLOYEE_ID>123</EMPLOYEE_ID>
<FIRST_NAME>Shanta</FIRST_NAME>
<LAST_NAME>Vollman</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="17">
<EMPLOYEE_ID>124</EMPLOYEE_ID>
<FIRST_NAME>Kevin</FIRST_NAME>
<LAST_NAME>Mourgos</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="18">
<EMPLOYEE_ID>125</EMPLOYEE_ID>
<FIRST_NAME>Julia</FIRST_NAME>
<LAST_NAME>Nayer</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="19">
<EMPLOYEE_ID>126</EMPLOYEE_ID>
<FIRST_NAME>Irene</FIRST_NAME>
<LAST_NAME>Mikkilineni</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="20">
<EMPLOYEE_ID>127</EMPLOYEE_ID>
<FIRST_NAME>James</FIRST_NAME>
<LAST_NAME>Landry</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="21">
<EMPLOYEE_ID>128</EMPLOYEE_ID>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>Markle</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="22">
<EMPLOYEE_ID>129</EMPLOYEE_ID>
<FIRST_NAME>Laura</FIRST_NAME>
<LAST_NAME>Bissot</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="23">
<EMPLOYEE_ID>130</EMPLOYEE_ID>
<FIRST_NAME>Mozhe</FIRST_NAME>
<LAST_NAME>Atkinson</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="24">
<EMPLOYEE_ID>131</EMPLOYEE_ID>
<FIRST_NAME>James</FIRST_NAME>
<LAST_NAME>Marlow</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="25">
<EMPLOYEE_ID>132</EMPLOYEE_ID>
<FIRST_NAME>TJ</FIRST_NAME>
<LAST_NAME>Olson</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="26">
<EMPLOYEE_ID>133</EMPLOYEE_ID>
<FIRST_NAME>Jason</FIRST_NAME>
<LAST_NAME>Mallin</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="27">
<EMPLOYEE_ID>134</EMPLOYEE_ID>
<FIRST_NAME>Michael</FIRST_NAME>
<LAST_NAME>Rogers</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="28">
<EMPLOYEE_ID>135</EMPLOYEE_ID>
<FIRST_NAME>Ki</FIRST_NAME>
<LAST_NAME>Gee</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="29">
<EMPLOYEE_ID>136</EMPLOYEE_ID>
<FIRST_NAME>Hazel</FIRST_NAME>
<LAST_NAME>Philtanker</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="30">
<EMPLOYEE_ID>137</EMPLOYEE_ID>
<FIRST_NAME>Renske</FIRST_NAME>
<LAST_NAME>Ladwig</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="31">
<EMPLOYEE_ID>138</EMPLOYEE_ID>
<FIRST_NAME>Stephen</FIRST_NAME>
<LAST_NAME>Stiles</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="32">
<EMPLOYEE_ID>139</EMPLOYEE_ID>
<FIRST_NAME>John</FIRST_NAME>
<LAST_NAME>Seo</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="33">
<EMPLOYEE_ID>140</EMPLOYEE_ID>
<FIRST_NAME>Joshua</FIRST_NAME>
<LAST_NAME>Patel</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="34">
<EMPLOYEE_ID>141</EMPLOYEE_ID>
<FIRST_NAME>Trenna</FIRST_NAME>
<LAST_NAME>Rajs</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="35">
<EMPLOYEE_ID>142</EMPLOYEE_ID>
<FIRST_NAME>Curtis</FIRST_NAME>
<LAST_NAME>Davies</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="36">
<EMPLOYEE_ID>143</EMPLOYEE_ID>
<FIRST_NAME>Randall</FIRST_NAME>
<LAST_NAME>Matos</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="37">
<EMPLOYEE_ID>144</EMPLOYEE_ID>
<FIRST_NAME>Peter</FIRST_NAME>
<LAST_NAME>Vargas</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="38">
<EMPLOYEE_ID>180</EMPLOYEE_ID>
<FIRST_NAME>Winston</FIRST_NAME>
<LAST_NAME>Taylor</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="39">
<EMPLOYEE_ID>181</EMPLOYEE_ID>
<FIRST_NAME>Jean</FIRST_NAME>
<LAST_NAME>Fleaur</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="40">
<EMPLOYEE_ID>182</EMPLOYEE_ID>
<FIRST_NAME>Martha</FIRST_NAME>
<LAST_NAME>Sullivan</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="41">
<EMPLOYEE_ID>183</EMPLOYEE_ID>
<FIRST_NAME>Girard</FIRST_NAME>
<LAST_NAME>Geoni</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="42">
<EMPLOYEE_ID>184</EMPLOYEE_ID>
<FIRST_NAME>Nandita</FIRST_NAME>
<LAST_NAME>Sarchand</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="43">
<EMPLOYEE_ID>185</EMPLOYEE_ID>
<FIRST_NAME>Alexis</FIRST_NAME>
<LAST_NAME>Bull</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="44">
<EMPLOYEE_ID>186</EMPLOYEE_ID>
<FIRST_NAME>Julia</FIRST_NAME>
<LAST_NAME>Dellinger</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="45">
<EMPLOYEE_ID>187</EMPLOYEE_ID>
<FIRST_NAME>Anthony</FIRST_NAME>
<LAST_NAME>Cabrio</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="46">
<EMPLOYEE_ID>188</EMPLOYEE_ID>
<FIRST_NAME>Kelly</FIRST_NAME>
<LAST_NAME>Chung</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="47">
<EMPLOYEE_ID>189</EMPLOYEE_ID>
<FIRST_NAME>Jennifer</FIRST_NAME>
<LAST_NAME>Dilly</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="48">
<EMPLOYEE_ID>190</EMPLOYEE_ID>
<FIRST_NAME>Timothy</FIRST_NAME>
<LAST_NAME>Gates</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="49">
<EMPLOYEE_ID>191</EMPLOYEE_ID>
<FIRST_NAME>Randall</FIRST_NAME>
<LAST_NAME>Perkins</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="50">
<EMPLOYEE_ID>192</EMPLOYEE_ID>
<FIRST_NAME>Sarah</FIRST_NAME>
<LAST_NAME>Bell</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="51">
<EMPLOYEE_ID>193</EMPLOYEE_ID>
<FIRST_NAME>Britney</FIRST_NAME>
<LAST_NAME>Everett</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="52">
<EMPLOYEE_ID>194</EMPLOYEE_ID>
<FIRST_NAME>Samuel</FIRST_NAME>
<LAST_NAME>McCain</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="53">
<EMPLOYEE_ID>195</EMPLOYEE_ID>
<FIRST_NAME>Vance</FIRST_NAME>
<LAST_NAME>Jones</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="54">
<EMPLOYEE_ID>196</EMPLOYEE_ID>
<FIRST_NAME>Alana</FIRST_NAME>
<LAST_NAME>Walsh</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="55">
<EMPLOYEE_ID>197</EMPLOYEE_ID>
<FIRST_NAME>Kevin</FIRST_NAME>
<LAST_NAME>Feeney</LAST_NAME>
<DEPARTMENT_NAME>Shipping</DEPARTMENT_NAME>
</Employee>
<Employee num="56">
<EMPLOYEE_ID>104</EMPLOYEE_ID>
<FIRST_NAME>Bruce</FIRST_NAME>
<LAST_NAME>Ernst</LAST_NAME>
<DEPARTMENT_NAME>IT</DEPARTMENT_NAME>
</Employee>
<Employee num="57">
<EMPLOYEE_ID>103</EMPLOYEE_ID>
<FIRST_NAME>Alexander</FIRST_NAME>
<LAST_NAME>Hunold</LAST_NAME>
<DEPARTMENT_NAME>IT</DEPARTMENT_NAME>
</Employee>
<Employee num="58">
<EMPLOYEE_ID>107</EMPLOYEE_ID>
<FIRST_NAME>Diana</FIRST_NAME>
<LAST_NAME>Lorentz</LAST_NAME>
<DEPARTMENT_NAME>IT</DEPARTMENT_NAME>
</Employee>
<Employee num="59">
<EMPLOYEE_ID>106</EMPLOYEE_ID>
<FIRST_NAME>Valli</FIRST_NAME>
<LAST_NAME>Pataballa</LAST_NAME>
<DEPARTMENT_NAME>IT</DEPARTMENT_NAME>
</Employee>
<Employee num="60">
<EMPLOYEE_ID>105</EMPLOYEE_ID>
<FIRST_NAME>David</FIRST_NAME>
<LAST_NAME>Austin</LAST_NAME>
<DEPARTMENT_NAME>IT</DEPARTMENT_NAME>
</Employee>
<Employee num="61">
<EMPLOYEE_ID>204</EMPLOYEE_ID>
<FIRST_NAME>Hermann</FIRST_NAME>
<LAST_NAME>Baer</LAST_NAME>
<DEPARTMENT_NAME>Public Relations</DEPARTMENT_NAME>
</Employee>
<Employee num="62">
<EMPLOYEE_ID>176</EMPLOYEE_ID>
<FIRST_NAME>Jonathon</FIRST_NAME>
<LAST_NAME>Taylor</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="63">
<EMPLOYEE_ID>177</EMPLOYEE_ID>
<FIRST_NAME>Jack</FIRST_NAME>
<LAST_NAME>Livingston</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="64">
<EMPLOYEE_ID>179</EMPLOYEE_ID>
<FIRST_NAME>Charles</FIRST_NAME>
<LAST_NAME>Johnson</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="65">
<EMPLOYEE_ID>175</EMPLOYEE_ID>
<FIRST_NAME>Alyssa</FIRST_NAME>
<LAST_NAME>Hutton</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="66">
<EMPLOYEE_ID>174</EMPLOYEE_ID>
<FIRST_NAME>Ellen</FIRST_NAME>
<LAST_NAME>Abel</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="67">
<EMPLOYEE_ID>173</EMPLOYEE_ID>
<FIRST_NAME>Sundita</FIRST_NAME>
<LAST_NAME>Kumar</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="68">
<EMPLOYEE_ID>172</EMPLOYEE_ID>
<FIRST_NAME>Elizabeth</FIRST_NAME>
<LAST_NAME>Bates</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="69">
<EMPLOYEE_ID>171</EMPLOYEE_ID>
<FIRST_NAME>William</FIRST_NAME>
<LAST_NAME>Smith</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="70">
<EMPLOYEE_ID>170</EMPLOYEE_ID>
<FIRST_NAME>Tayler</FIRST_NAME>
<LAST_NAME>Fox</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="71">
<EMPLOYEE_ID>169</EMPLOYEE_ID>
<FIRST_NAME>Harrison</FIRST_NAME>
<LAST_NAME>Bloom</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="72">
<EMPLOYEE_ID>168</EMPLOYEE_ID>
<FIRST_NAME>Lisa</FIRST_NAME>
<LAST_NAME>Ozer</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="73">
<EMPLOYEE_ID>145</EMPLOYEE_ID>
<FIRST_NAME>John</FIRST_NAME>
<LAST_NAME>Russell</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="74">
<EMPLOYEE_ID>146</EMPLOYEE_ID>
<FIRST_NAME>Karen</FIRST_NAME>
<LAST_NAME>Partners</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="75">
<EMPLOYEE_ID>147</EMPLOYEE_ID>
<FIRST_NAME>Alberto</FIRST_NAME>
<LAST_NAME>Errazuriz</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="76">
<EMPLOYEE_ID>148</EMPLOYEE_ID>
<FIRST_NAME>Gerald</FIRST_NAME>
<LAST_NAME>Cambrault</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="77">
<EMPLOYEE_ID>149</EMPLOYEE_ID>
<FIRST_NAME>Eleni</FIRST_NAME>
<LAST_NAME>Zlotkey</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="78">
<EMPLOYEE_ID>150</EMPLOYEE_ID>
<FIRST_NAME>Peter</FIRST_NAME>
<LAST_NAME>Tucker</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="79">
<EMPLOYEE_ID>151</EMPLOYEE_ID>
<FIRST_NAME>David</FIRST_NAME>
<LAST_NAME>Bernstein</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="80">
<EMPLOYEE_ID>152</EMPLOYEE_ID>
<FIRST_NAME>Peter</FIRST_NAME>
<LAST_NAME>Hall</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="81">
<EMPLOYEE_ID>153</EMPLOYEE_ID>
<FIRST_NAME>Christopher</FIRST_NAME>
<LAST_NAME>Olsen</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="82">
<EMPLOYEE_ID>154</EMPLOYEE_ID>
<FIRST_NAME>Nanette</FIRST_NAME>
<LAST_NAME>Cambrault</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="83">
<EMPLOYEE_ID>155</EMPLOYEE_ID>
<FIRST_NAME>Oliver</FIRST_NAME>
<LAST_NAME>Tuvault</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="84">
<EMPLOYEE_ID>156</EMPLOYEE_ID>
<FIRST_NAME>Janette</FIRST_NAME>
<LAST_NAME>King</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="85">
<EMPLOYEE_ID>157</EMPLOYEE_ID>
<FIRST_NAME>Patrick</FIRST_NAME>
<LAST_NAME>Sully</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="86">
<EMPLOYEE_ID>158</EMPLOYEE_ID>
<FIRST_NAME>Allan</FIRST_NAME>
<LAST_NAME>McEwen</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="87">
<EMPLOYEE_ID>159</EMPLOYEE_ID>
<FIRST_NAME>Lindsey</FIRST_NAME>
<LAST_NAME>Smith</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="88">
<EMPLOYEE_ID>160</EMPLOYEE_ID>
<FIRST_NAME>Louise</FIRST_NAME>
<LAST_NAME>Doran</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="89">
<EMPLOYEE_ID>161</EMPLOYEE_ID>
<FIRST_NAME>Sarath</FIRST_NAME>
<LAST_NAME>Sewall</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="90">
<EMPLOYEE_ID>162</EMPLOYEE_ID>
<FIRST_NAME>Clara</FIRST_NAME>
<LAST_NAME>Vishney</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="91">
<EMPLOYEE_ID>163</EMPLOYEE_ID>
<FIRST_NAME>Danielle</FIRST_NAME>
<LAST_NAME>Greene</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="92">
<EMPLOYEE_ID>164</EMPLOYEE_ID>
<FIRST_NAME>Mattea</FIRST_NAME>
<LAST_NAME>Marvins</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="93">
<EMPLOYEE_ID>165</EMPLOYEE_ID>
<FIRST_NAME>David</FIRST_NAME>
<LAST_NAME>Lee</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="94">
<EMPLOYEE_ID>166</EMPLOYEE_ID>
<FIRST_NAME>Sundar</FIRST_NAME>
<LAST_NAME>Ande</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="95">
<EMPLOYEE_ID>167</EMPLOYEE_ID>
<FIRST_NAME>Amit</FIRST_NAME>
<LAST_NAME>Banda</LAST_NAME>
<DEPARTMENT_NAME>Sales</DEPARTMENT_NAME>
</Employee>
<Employee num="96">
<EMPLOYEE_ID>101</EMPLOYEE_ID>
<FIRST_NAME>Neena</FIRST_NAME>
<LAST_NAME>Kochhar</LAST_NAME>
<DEPARTMENT_NAME>Executive</DEPARTMENT_NAME>
</Employee>
<Employee num="97">
<EMPLOYEE_ID>100</EMPLOYEE_ID>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>King</LAST_NAME>
<DEPARTMENT_NAME>Executive</DEPARTMENT_NAME>
</Employee>
<Employee num="98">
<EMPLOYEE_ID>102</EMPLOYEE_ID>
<FIRST_NAME>Lex</FIRST_NAME>
<LAST_NAME>De Haan</LAST_NAME>
<DEPARTMENT_NAME>Executive</DEPARTMENT_NAME>
</Employee>
<Employee num="99">
<EMPLOYEE_ID>110</EMPLOYEE_ID>
<FIRST_NAME>John</FIRST_NAME>
<LAST_NAME>Chen</LAST_NAME>
<DEPARTMENT_NAME>Finance</DEPARTMENT_NAME>
</Employee>
<Employee num="100">
<EMPLOYEE_ID>108</EMPLOYEE_ID>
<FIRST_NAME>Nancy</FIRST_NAME>
<LAST_NAME>Greenberg</LAST_NAME>
<DEPARTMENT_NAME>Finance</DEPARTMENT_NAME>
</Employee>
<Employee num="101">
<EMPLOYEE_ID>111</EMPLOYEE_ID>
<FIRST_NAME>Ismael</FIRST_NAME>
<LAST_NAME>Sciarra</LAST_NAME>
<DEPARTMENT_NAME>Finance</DEPARTMENT_NAME>
</Employee>
<Employee num="102">
<EMPLOYEE_ID>112</EMPLOYEE_ID>
<FIRST_NAME>Jose Manuel</FIRST_NAME>
<LAST_NAME>Urman</LAST_NAME>
<DEPARTMENT_NAME>Finance</DEPARTMENT_NAME>
</Employee>
<Employee num="103">
<EMPLOYEE_ID>113</EMPLOYEE_ID>
<FIRST_NAME>Luis</FIRST_NAME>
<LAST_NAME>Popp</LAST_NAME>
<DEPARTMENT_NAME>Finance</DEPARTMENT_NAME>
</Employee>
<Employee num="104">
<EMPLOYEE_ID>109</EMPLOYEE_ID>
<FIRST_NAME>Daniel</FIRST_NAME>
<LAST_NAME>Faviet</LAST_NAME>
<DEPARTMENT_NAME>Finance</DEPARTMENT_NAME>
</Employee>
<Employee num="105">
<EMPLOYEE_ID>206</EMPLOYEE_ID>
<FIRST_NAME>William</FIRST_NAME>
<LAST_NAME>Gietz</LAST_NAME>
<DEPARTMENT_NAME>Accounting</DEPARTMENT_NAME>
</Employee>
<Employee num="106">
<EMPLOYEE_ID>205</EMPLOYEE_ID>
<FIRST_NAME>Shelley</FIRST_NAME>
<LAST_NAME>Higgins</LAST_NAME>
<DEPARTMENT_NAME>Accounting</DEPARTMENT_NAME>
</Employee>
</Employees>


Note that this generated XML has the "Employees" root tag and "Employee" row tags just as we specified with OracleXMLQuery. The rest of the XML elements are named based on the names of the columns in the SELECT statement and are all in uppercase. These individual element names correspond with the four columns in the SELECT clause.

It is useful to have the XML shown above generated by OracleXMLQuery, but XML is often much more useful if we have a schema defining it. This is especially true if using technologies such as web services that require an XML schema. When you have example XML files but lack a schema definition for them, Trang comes to the rescue.

The next screen snapshot (click on image to see larger version) displays the Trang help menu when unzipped from its downloadable ZIP file and executed with the Java launcher using the java -jar trang.jar command (trang.jar is an executable JAR) without any options.



To generate a W3C XML Schema that defines the generated XML shown above, run the executable trang.jar command again, but this time specify an input file (the generated XML shown above) and specify an output file after that. In this case, I am running this command as: java -jar trang.jar employees.xml employees.xsd. Trang detects that I want the a W3C XML Schema definition generated for the provided XML file because it recognizes the first listed argument as an XML file based on its extension (.xml) and recognizes the target format based on its extension (.xsd). The Trang manual also explains that you can use explicit options to specify the types of conversions to take place if you don't want to rely solely on file extensions.

When the executable JAR trang.jar is executed as described above, the XSD file is generated that describes the input XML file. That generated XSD file is shown next:

employees.xsd - W3C XML Schema Generated by Trang
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Employees">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="Employee"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element ref="EMPLOYEE_ID"/>
<xs:element ref="FIRST_NAME"/>
<xs:element ref="LAST_NAME"/>
<xs:element ref="DEPARTMENT_NAME"/>
</xs:sequence>
<xs:attribute name="num" use="required" type="xs:integer"/>
</xs:complexType>
</xs:element>
<xs:element name="EMPLOYEE_ID" type="xs:integer"/>
<xs:element name="FIRST_NAME" type="xs:string"/>
<xs:element name="LAST_NAME" type="xs:string"/>
<xs:element name="DEPARTMENT_NAME" type="xs:string"/>
</xs:schema>


Without much effort on my part, I have a W3C XML Schema file that describes my generated XML. In practical terms, I am likely still going to need to narrow down some of the definitions because it is no surprise that Trang cannot detect more granular datatypes than general types like xs:string. So, I will almost certainly need to create more granular schema types if desired. However, this gives me a compliant starting point to add more specific details as desired.

We are not limited to generating W3C XML Schema with Trang. We can also generate the older, less descriptive Document Type Definition (DTD) with the command: java -jar trang.jar employees.xml employees.dtd. The next listing demonstrates a DTD generated with just such a command.

employees.dtd - Generated by Trang
<?xml encoding="UTF-8"?>

<!ELEMENT Employees (Employee)+>
<!ATTLIST Employees
xmlns CDATA #FIXED ''>

<!ELEMENT Employee (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,DEPARTMENT_NAME)>
<!ATTLIST Employee
xmlns CDATA #FIXED ''
num  #REQUIRED>

<!ELEMENT EMPLOYEE_ID (#PCDATA)>
<!ATTLIST EMPLOYEE_ID
xmlns CDATA #FIXED ''>

<!ELEMENT FIRST_NAME (#PCDATA)>
<!ATTLIST FIRST_NAME
xmlns CDATA #FIXED ''>

<!ELEMENT LAST_NAME (#PCDATA)>
<!ATTLIST LAST_NAME
xmlns CDATA #FIXED ''>

<!ELEMENT DEPARTMENT_NAME (#PCDATA)>
<!ATTLIST DEPARTMENT_NAME
xmlns CDATA #FIXED ''>


Trang also allows generation of regular RelaxNG and compact RelaxNG schema definition formats as well. The simple changes to the command to get these two formats as well as the output from each are shown next.

employees.rng - Generated with java -jar trang.jar employees.xml employees.rng
<?xml version="1.0" encoding="UTF-8"?>
<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<element name="Employees">
<oneOrMore>
<element name="Employee">
<attribute name="num">
<data type="integer"/>
</attribute>
<element name="EMPLOYEE_ID">
<data type="integer"/>
</element>
<element name="FIRST_NAME">
<text/>
</element>
<element name="LAST_NAME">
<text/>
</element>
<element name="DEPARTMENT_NAME">
<text/>
</element>
</element>
</oneOrMore>
</element>
</start>
</grammar>


employees.rnc - Generated with java -jar trang.jar employees.xml employees.rnc
default namespace = ""

start =
element Employees {
element Employee {
attribute num { xsd:integer },
element EMPLOYEE_ID { xsd:integer },
element FIRST_NAME { text },
element LAST_NAME { text },
element DEPARTMENT_NAME { text }
}+
}


With the two above examples of RELAX NG schema generation covered, the screen in which all four of these commands were run to generate XML Schema, DTD, RELAX NG, and compact RELAX NG are shown in the next screenshot. Note that there is no obvious output of the generated files, but the files will be found in the directory. For organizational purposes, I had my employees.xml file in a subdirectory called "input" and that is specified as part of the input file name.



Trang allows for multiple XML files to be specified as input as long as they are all passed in before the schema file that you want generated. This is useful if you want to generate one of the four schema types for a collection of related but not necessarily exactly the same XML source documents.

Another common use of Trang, especially in years past, was to migrate existing DTDs to W3C XML Schema. DTDs are necessarily less descriptive than W3C XML Schema, but such a conversion could at least get one started on a compliant Schema that could have greater description added.

Finally, in earlier versions of Java SE 6 there was a bug that prevented Trang from working correctly. However, I ran the examples shown here in Java SE 6, confirming that this bug has been fixed and closed.

The following are some links to Trang-related resources. Some of these were cited above as embedded links.

No comments: