I have a java agent in lotus notes in which i receive an xml and parse this.
this is the code:
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Arrays;
public class JavaAgent extends AgentBase {
private static PrintWriter pw;
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
Database db = agentContext.getCurrentDatabase();
//domino 03
boolean ProductieDatabase = false;
String ApplicatieServer = "CN=Server01";
String OrderDB = "General\\Order.nsf";
String TestOrderDB = "General\\TestOrder.nsf";
String Relations= "General\\Relations.nsf";
String Tabel= "General\\Tabel.nsf";
org.w3c.dom.Document domdoc = null;
lotus.domino.Document doc = agentContext.getDocumentContext();
Item requestContent = null;
StringBuffer sb = new StringBuffer();
pw = getAgentOutput();
//Open databases
Database RelationDB= session.getDatabase(ApplicatieServer,Relations, false);
Database TabelDB= session.getDatabase(ApplicatieServer,Tabel, false);
//Open order database
Database TabelDB;
if(ProductieDatabase == true)
{
TabelDB= session.getDatabase(ApplicatieServer,OrderDB, false);
}
else
{
TabelDB= session.getDatabase(ApplicatieServer,TestOrderDB, false);
}
//Maak nieuw request document aan
lotus.domino.Document RequestDoc = db.createDocument();
//Alle velden uit de http post toevoegen aan document
Vector items = doc.getItems();
for (int j=0; j<items.size(); j++)
{
// System.out.println ("Testorders 3");
Item item = (Item)items.elementAt(j);
String fldName = item.getName();
String fldValue = item.getValueString();
RequestDoc.replaceItemValue(fldName, fldValue);
if ( fldName.matches("(?i).*request_content.*") )
{
sb.append( fldValue );
}
}
RequestDoc.replaceItemValue("Form", "Response");
RequestDoc.replaceItemValue("Status", "0");
RequestDoc.replaceItemValue("ID_Request", RequestDoc.getUniversalID());
Date currentDate=new Date(System.currentTimeMillis());
SimpleDateFormat formatterDatum=new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat formatterTijd=new SimpleDateFormat("HHmmss");
String HubwooBestandspad = "C:\\OCI\\asd\\";
String Bestnaam = cxvxcv+ "asdasd" + RequestDoc.getUniversalID() + "_" + formatterDatum.format(currentDate) + "_" + formatterTijd.format(currentDate) + ".xml";
Stream outStream = session.createStream();
if (outStream.open(Bestnaam, "ASCII")) {
if (outStream.getBytes() == 0) {
outStream.writeText(sb.toString());
outStream.close();
}
else
System.out.println("Output file exists and has content");
}
else{
System.out.println("Output file open failed");
}
File input = new File(Bestnaam);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
domdoc = dBuilder.parse(input);
domdoc.getDocumentElement().normalize();
NodeList nList = domdoc.getElementsByTagName("ItemOut");
String test = "TEST OCI AGENT";
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
Element eElement = (Element) nNode;
System.out.println("\nCurrent Element :" + nList.getLength());
test = test + "**Delivery Date**" + eElement.getAttribute("requestedDeliveryDate") + "!END! [" + temp + "]";
test = test + " " + eElement.getElementsByTagName("SupplierPartID").item(0).getTextContent();
test = test + " " + eElement.getElementsByTagName("Description").item(0).getTextContent();
}
RequestDoc.replaceItemValue("JSON", sb.toString());
RequestDoc.replaceItemValue("JSON", test);
// OM HELE XML FILE TE KRIJGEN
RequestDoc.replaceItemValue("XmlTU",sb.toString());
RequestDoc.save();
//verander content-type
pw.println("Content-Type: text/xml");
//verander charset
pw.println("charset: UFT-8");
//stuur 200 OK terug
pw.println("200 OK");
}
catch(Exception e) {
e.printStackTrace();
}
}
}
How can i change sucessfully the content type to text/xml and the charset to utf-8. I was thinking about creating an extra class which extends the HttpServlet and which has the doPost method. But how can i then implement that object in to this agent?
Now this service works, with firefox poster i also receive response 200 OK and also content-type= text/xml.. But if this service is getting called from a .net envorinment then the .net shows a protocol violation error.
Can someone help?
code of the .net application:
Public Function SubmitOrder(ByVal OrderXML, ByVal URL)
Dim objXMLHTTP 'MSXML2.ServerXMLHTTP
'We provide our own error handling
On Error Resume Next
'The MSXML2.ServerXMLHTTP object allows xml to be posted to
'external webpages.
Set objXMLHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
If Err.Number <> 0 Then
SubmitOrder = "ERROR: Failed to create ServerXMLHTTP - " & Err.Description
Exit Function
End If
'Specify the webpage we wish to use
objXMLHTTP.Open "POST", URL, False
If Err.Number <> 0 Then
SubmitOrder = "ERROR: Failed to open URL - " & Err.Description
Exit Function
End If
'The type of information we are sending
objXMLHTTP.setRequestHeader "Content-Type", "text/xml"
If Err.Number <> 0 Then
SubmitOrder = "ERROR: Failed to setRequestHeader - " & Err.Description
Exit Function
End If
'Send the information
objXMLHTTP.send replace(OrderXML,"UTF-16","UTF-8")
If Err.Number <> 0 Then
SubmitOrder = "ERROR: Failed to send data to " & URL & " - " & Err.Description & ", Error number --> " & Err.Number
Exit Function
End If
'Return the result
SubmitOrder = objXMLHTTP.responseText
end Function
public Function CheckSuccess(ByVal Response)
'Check for any internal errors
If Left(Response, 6) = "ERROR:" Then
CheckSuccess = False
Exit Function
End If
'If the response includes the text code="200" then the
'export was a success
CheckSuccess = instr(Response, "code=""200""") <> 0
End Function
This problem really has me scratching my head.
I have a chat application that parses xml from the server. It is successful parsing the message text, msg id, but I am getting a nullpointerException for the UserID but I am pulling it from the same location. Please help
// Get messages
NodeList messageList = documentElement.getElementsByTagName("MESSAGE");
ret.messages = new ChatStruct[messageList.getLength()];
Log.v("response","Message Length " + messageList.getLength());
for (int i = 0; i < messageList.getLength(); i++) {
Element messageNode = (Element) messageList.item(i);
ret.messages[i] = new ChatStruct();
// Get messageId
try {
Element messageIdNode = (Element) messageNode.getElementsByTagName("ID").item(0);
String messageId = messageIdNode.getFirstChild().getNodeValue();
System.out.println("messageId = " + messageId);
ret.messages[i].id = Long.parseLong(messageId);
//Log.v("Util","Message ID " + Long.parseLong(messageId));
} catch (Exception e) {
ret.messages[i].id = 0l;
// e.printStackTrace();
}
// Get text
try {
Element textNode = (Element) messageNode.getElementsByTagName("TEXT").item(0);
String text = textNode.getFirstChild().getNodeValue();
System.out.println("text = " + text);
ret.messages[i].textMessage = text.trim();
//Log.v("Util","Message text " + text.trim());
} catch (Exception e) {
ret.messages[i].textMessage = "";
// e.printStackTrace();
}
// Get userId
try {
//ret.messages[i].userId = 1;
//Log.v("Util # userID node","userID should be 1");
Element userIdNode = (Element) messageNode.getElementsByTagName("USERID").item(0);
Log.i("Util # userID node","userIdNode set");
String userId = userIdNode.getFirstChild().getNodeValue();
//String userId = "1";
Log.i("Util # userID node","userId String set");
System.out.println("userId = " + userId);
ret.messages[i].userId = Long.parseLong(userId);
//ret.messages[i].userId = 1;
} catch (Exception e) {
Log.v("Util # userID node", "there was an error " + e);
ret.messages[i].userId = 0l;
// e.printStackTrace();
}
I can hard code the string and it works but other than that the error occurs at
String userId = userIdNode.getFirstChild().getNodeValue();
It makes it up to commented line of code confirming the userIDNode is set
I can't figure out why userID is not coming in from the server here is the XML:
<MESSAGE>
<ID><?php echo $row_shouts['msgid']; ?></ID>
<USERID><?php echo $row_shouts['userid']; ?></USERID>
<GENDER><?php echo $row_shouts['gender']; ?></GENDER>
<ONLINE><?php echo $row_shouts['account_status'];?></ONLINE>
<TDATE><?php echo datee("h:i:s M, d Y", strtotime($row_shouts['date'])); ?></TDATE>
<ICONID><?php echo $iconid; ?></ICONID>
<PIC><?php echo $PIC; ?></PIC>
<MSGPIC><?php echo $row_shouts['media']; ?></MSGPIC>
<PICDATE><?php echo strtotime($row_shouts['picdate']); ?></PICDATE>
<ALIAS><![CDATA[<?php echo $row_shouts['nickname'];?>]]></ALIAS>
<TEXT><![CDATA[<?php echo $mesg;?>]]></TEXT>
</MESSAGE>
Did you check with the DTD file for the supplied Xml, May be USERID is not clearly defined there.
[please share the error logs]
What's the execption say if you print the stack trace? It might be because the user id isn't a long and you're trying to parse it. I don't see any errors in the retrieval of the user id.
I need to parse XML file and create bunch of objects from ArrayList with reflection.
I achieved this with Class.forName().
Here is my code:
public ArrayList<Sweets> parse(String fileName) throws Exception {
File file = new File(fileName);
Document doc = builder.parse(file);
ArrayList<Sweets> items = new ArrayList<Sweets>();
int itemCount = Integer.parseInt(path
.evaluate("count(/gift/item)", doc));
for (int i = 1; i <= itemCount; i++) {
double sugar = Double.parseDouble(path.evaluate("/gift/item[" + i + "]/#sugar", doc));
String name = path.evaluate("/gift/item[" + i + "]/name", doc);
double weight = Double.parseDouble(path.evaluate("/gift/item[" + i
+ "]/weight", doc));
Class cl = Class.forName("com.epam.lab.model.chocolate." + name);
items.add((Sweets) cl.getConstructor(double.class, double.class)
.newInstance(sugar, weight));
}
return items;
}
It works but at this line:
Class cl = Class.forName("com.epam.lab.model.chocolate." + name);
But some disadvantage is that this method need to have full name of class include packages.
It takes exactly from distinct package. But I need to take other classes from other location. Limitation of forName() doesn't let me do this.
How to circumvent Class.forName() constraints?
There is a nice alternative to reading and parsing XML into Java objects: JAXB with annotations.
Reading by:
MyDoc doc = load(MyDoc.class, "/mydoc.xml");
private <T> T load(Class<T> klazz, String xmlResource) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(klazz);
return klazz.cast(jaxbContext.createUnmarshaller()
.unmarshal(getClass().getResourceAsStream(xmlResource)));
} catch (JAXBException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE,
"Cannot read resource " + xmlResource, e);
throw new IllegalStateException(e);
}
}
#XmlRootElement(name="document")
public class MyDoc {
#XmlElement(name="sweetsList")
public List<Sweets> sweets= new ArrayList<>();
}
<document>
<sweetsList>
...
</sweetsList>
</document>
And same annotations with #XmlElement and #XmlAttribute for the other classes.
I'm afraid it's not possible - to instantiate you need to provide fully qualified name of the class.
But maybe you can provide more information in parsed xml - e.g. part of the package name which differs between types of sweets?
String name = path.evaluate("/gift/item[" + i + "]/name", doc);
String type = path.evaluate("/gift/item[" + i + "]/type", doc);
double weight = Double.parseDouble(path.evaluate("/gift/item[" + i + "]/weight", doc));
Class cl = Class.forName("com.epam.lab.model" + type + "." + name);
Or if XML format is sealed, then maybe you can create a mapping between particular sweets names and packages of classess which represent them?
I have an XmlParserClass to get values from the xml file which looks like this.
<?xml version="1.0" encoding="utf-8" ?>
<HomePageData>
<LogoTopLeft>//*[#id='corp_logo']</LogoTopLeft>
<SingInLink>//*[#id='login']</SingInLink>
<SingUpLink>//*[#id='signup']</SingUpLink>
</HomePageData>
And the method in my class file looks like this:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
XPath xp = XPathFactory.newInstance().newXPath();
try{
String value = xp.evaluate("/LogoTopLeft/text()", doc);
return value;
} catch(XPathExpressionException e)
{
return null;
}
I am not able to get the expected data from the xml file using this class file. It just reaches the try block and then come to the catch to return "null". Most of the question in stackoverflow has been answered with a for loop to collect all nodes, but I need to take one data at a time not allelements at one stretch and Also, I need to return this value to another class file which will accept only STRINGS and so I cant pass NodeList or any other elements
P.S - The xml file is present in a different location other than the parsefile. I stored the class path value "/projName/src/com/core/path/indexPage.xml" in a file and passed it.
You just need to fix your XPath. /LogoTopLeft is looking for the element at XML root whereas it's a child element. So, either use //LogoTopLeft or specify the full path as /HomePageData/LogoTopLeft
String logo = xp.evaluate("//LogoTopLeft/text()", doc);
String signIn = xp.evaluate("//SignInLink/text()", doc);
String signUp = xp.evaluate("//SignUpLink/text()", doc);
System.out.println( "logo = " + logo +
"; signIn = " + signIn +
"; signUp = " + signUp);
/* prints:
logo = //*[#id='corp_logo']; signIn = //*[#id='login']; signUp = //*[#id='signup']
*/
EDIT : (My Test Code)
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(new File("input.xml"));
XPath xp = XPathFactory.newInstance().newXPath();
try {
String logo = xp.evaluate("/HomePageData/LogoTopLeft/text()", doc);
String signIn = xp.evaluate("//SignInLink/text()", doc);
String signUp = xp.evaluate("//SignUpLink/text()", doc);
System.out.println( "logo = " + logo +
"; signIn = " + signIn +
"; signUp = " + signUp);
} catch (XPathExpressionException e) {
e.printStackTrace();
}
input.xml (placed in project directory)
<?xml version="1.0" encoding="utf-8" ?>
<HomePageData>
<LogoTopLeft>//*[#id='corp_logo']</LogoTopLeft>
<SignInLink>//*[#id='login']</SignInLink>
<SignUpLink>//*[#id='signup']</SignUpLink>
</HomePageData>
I'd like to be able to read in an XML schema (i.e. xsd) and from that know what are valid attributes, child elements, values as I walk through it.
For example, let's say I have an xsd that this xml will validate against:
<root>
<element-a type="something">
<element-b>blah</element-b>
<element-c>blahblah</element-c>
</element-a>
</root>
I've tinkered with several libraries and I can confidently get <root> as the root element. Beyond that I'm lost.
Given an element I need to know what child elements are required or allowed, attributes, facets, choices, etc. Using the above example I'd want to know that element-a has an attribute type and may have children element-b and element-c...or must have children element-b and element-c...or must have one of each...you get the picture I hope.
I've looked at numerous libraries such as XSOM, Eclipse XSD, Apache XmlSchema and found they're all short on good sample code. My search of the Internet has also been unsuccessful.
Does anyone know of a good example or even a book that demonstrates how to go through an XML schema and find out what would be valid options at a given point in a validated XML document?
clarification
I'm not looking to validate a document, rather I'd like to know the options at a given point to assist in creating or editing a document. If I know "I am here" in a document, I'd like to determing what I can do at that point. "Insert one of element A, B, or C" or "attach attribute 'description'".
This is a good question. Although, it is old, I did not find an acceptable answer. The thing is that the existing libraries I am aware of (XSOM, Apache XmlSchema) are designed as object models. The implementors did not have the intention to provide any utility methods — you should consider implement them yourself using the provided object model.
Let's see how querying context-specific elements can be done by the means of Apache XmlSchema.
You can use their tutorial as a starting point. In addition, Apache CFX framework provides the XmlSchemaUtils class with lots of handy code examples.
First of all, read the XmlSchemaCollection as illustrated by the library's tutorial:
XmlSchemaCollection xmlSchemaCollection = new XmlSchemaCollection();
xmlSchemaCollection.read(inputSource, new ValidationEventHandler());
Now, XML Schema defines two kinds of data types:
Simple types
Complex types
Simple types are represented by the XmlSchemaSimpleType class. Handling them is easy. Read the documentation: https://ws.apache.org/commons/XmlSchema/apidocs/org/apache/ws/commons/schema/XmlSchemaSimpleType.html. But let's see how to handle complex types. Let's start with a simple method:
#Override
public List<QName> getChildElementNames(QName parentElementName) {
XmlSchemaElement element = xmlSchemaCollection.getElementByQName(parentElementName);
XmlSchemaType type = element != null ? element.getSchemaType() : null;
List<QName> result = new LinkedList<>();
if (type instanceof XmlSchemaComplexType) {
addElementNames(result, (XmlSchemaComplexType) type);
}
return result;
}
XmlSchemaComplexType may stand for both real type and for the extension element. Please see the public static QName getBaseType(XmlSchemaComplexType type) method of the XmlSchemaUtils class.
private void addElementNames(List<QName> result, XmlSchemaComplexType type) {
XmlSchemaComplexType baseType = getBaseType(type);
XmlSchemaParticle particle = baseType != null ? baseType.getParticle() : type.getParticle();
addElementNames(result, particle);
}
When you handle XmlSchemaParticle, consider that it can have multiple implementations. See: https://ws.apache.org/commons/XmlSchema/apidocs/org/apache/ws/commons/schema/XmlSchemaParticle.html
private void addElementNames(List<QName> result, XmlSchemaParticle particle) {
if (particle instanceof XmlSchemaAny) {
} else if (particle instanceof XmlSchemaElement) {
} else if (particle instanceof XmlSchemaGroupBase) {
} else if (particle instanceof XmlSchemaGroupRef) {
}
}
The other thing to bear in mind is that elements can be either abstract or concrete. Again, the JavaDocs are the best guidance.
Many of the solutions for validating XML in java use the JAXB API. There's an extensive tutorial available here. The basic recipe for doing what you're looking for with JAXB is as follows:
Obtain or create the XML schema to validate against.
Generate Java classes to bind the XML to using xjc, the JAXB compiler.
Write java code to:
Open the XML content as an input stream.
Create a JAXBContext and Unmarshaller
Pass the input stream to the Unmarshaller's unmarshal method.
The parts of the tutorial you can read for this are:
Hello, world
Unmarshalling XML
I see you have tried Eclipse XSD. Have you tried Eclipse Modeling Framework (EMF)? You can:
Generating an EMF Model using XML Schema (XSD)
Create a dynamic instance from your metamodel (3.1 With the dynamic instance creation tool)
This is for exploring the xsd. You can create the dynamic instance of the root element then you can right click the element and create child element. There you will see what the possible children element and so on.
As for saving the created EMF model to an xml complied xsd: I have to look it up. I think you can use JAXB for that (How to use EMF to read XML file?).
Some refs:
EMF: Eclipse Modeling Framework, 2nd Edition (written by creators)
Eclipse Modeling Framework (EMF)
Discover the Eclipse Modeling Framework (EMF) and Its Dynamic Capabilities
Creating Dynamic EMF Models From XSDs and Loading its Instances From XML as SDOs
This is a fairly complete sample on how to parse an XSD using XSOM:
import java.io.File;
import java.util.Iterator;
import java.util.Vector;
import org.xml.sax.ErrorHandler;
import com.sun.xml.xsom.XSComplexType;
import com.sun.xml.xsom.XSElementDecl;
import com.sun.xml.xsom.XSFacet;
import com.sun.xml.xsom.XSModelGroup;
import com.sun.xml.xsom.XSModelGroupDecl;
import com.sun.xml.xsom.XSParticle;
import com.sun.xml.xsom.XSRestrictionSimpleType;
import com.sun.xml.xsom.XSSchema;
import com.sun.xml.xsom.XSSchemaSet;
import com.sun.xml.xsom.XSSimpleType;
import com.sun.xml.xsom.XSTerm;
import com.sun.xml.xsom.impl.Const;
import com.sun.xml.xsom.parser.XSOMParser;
import com.sun.xml.xsom.util.DomAnnotationParserFactory;
public class XSOMNavigator
{
public static class SimpleTypeRestriction
{
public String[] enumeration = null;
public String maxValue = null;
public String minValue = null;
public String length = null;
public String maxLength = null;
public String minLength = null;
public String[] pattern = null;
public String totalDigits = null;
public String fractionDigits = null;
public String whiteSpace = null;
public String toString()
{
String enumValues = "";
if (enumeration != null)
{
for(String val : enumeration)
{
enumValues += val + ", ";
}
enumValues = enumValues.substring(0, enumValues.lastIndexOf(','));
}
String patternValues = "";
if (pattern != null)
{
for(String val : pattern)
{
patternValues += "(" + val + ")|";
}
patternValues = patternValues.substring(0, patternValues.lastIndexOf('|'));
}
String retval = "";
retval += minValue == null ? "" : "[MinValue = " + minValue + "]\t";
retval += maxValue == null ? "" : "[MaxValue = " + maxValue + "]\t";
retval += minLength == null ? "" : "[MinLength = " + minLength + "]\t";
retval += maxLength == null ? "" : "[MaxLength = " + maxLength + "]\t";
retval += pattern == null ? "" : "[Pattern(s) = " + patternValues + "]\t";
retval += totalDigits == null ? "" : "[TotalDigits = " + totalDigits + "]\t";
retval += fractionDigits == null ? "" : "[FractionDigits = " + fractionDigits + "]\t";
retval += whiteSpace == null ? "" : "[WhiteSpace = " + whiteSpace + "]\t";
retval += length == null ? "" : "[Length = " + length + "]\t";
retval += enumeration == null ? "" : "[Enumeration Values = " + enumValues + "]\t";
return retval;
}
}
private static void initRestrictions(XSSimpleType xsSimpleType, SimpleTypeRestriction simpleTypeRestriction)
{
XSRestrictionSimpleType restriction = xsSimpleType.asRestriction();
if (restriction != null)
{
Vector<String> enumeration = new Vector<String>();
Vector<String> pattern = new Vector<String>();
for (XSFacet facet : restriction.getDeclaredFacets())
{
if (facet.getName().equals(XSFacet.FACET_ENUMERATION))
{
enumeration.add(facet.getValue().value);
}
if (facet.getName().equals(XSFacet.FACET_MAXINCLUSIVE))
{
simpleTypeRestriction.maxValue = facet.getValue().value;
}
if (facet.getName().equals(XSFacet.FACET_MININCLUSIVE))
{
simpleTypeRestriction.minValue = facet.getValue().value;
}
if (facet.getName().equals(XSFacet.FACET_MAXEXCLUSIVE))
{
simpleTypeRestriction.maxValue = String.valueOf(Integer.parseInt(facet.getValue().value) - 1);
}
if (facet.getName().equals(XSFacet.FACET_MINEXCLUSIVE))
{
simpleTypeRestriction.minValue = String.valueOf(Integer.parseInt(facet.getValue().value) + 1);
}
if (facet.getName().equals(XSFacet.FACET_LENGTH))
{
simpleTypeRestriction.length = facet.getValue().value;
}
if (facet.getName().equals(XSFacet.FACET_MAXLENGTH))
{
simpleTypeRestriction.maxLength = facet.getValue().value;
}
if (facet.getName().equals(XSFacet.FACET_MINLENGTH))
{
simpleTypeRestriction.minLength = facet.getValue().value;
}
if (facet.getName().equals(XSFacet.FACET_PATTERN))
{
pattern.add(facet.getValue().value);
}
if (facet.getName().equals(XSFacet.FACET_TOTALDIGITS))
{
simpleTypeRestriction.totalDigits = facet.getValue().value;
}
if (facet.getName().equals(XSFacet.FACET_FRACTIONDIGITS))
{
simpleTypeRestriction.fractionDigits = facet.getValue().value;
}
if (facet.getName().equals(XSFacet.FACET_WHITESPACE))
{
simpleTypeRestriction.whiteSpace = facet.getValue().value;
}
}
if (enumeration.size() > 0)
{
simpleTypeRestriction.enumeration = enumeration.toArray(new String[] {});
}
if (pattern.size() > 0)
{
simpleTypeRestriction.pattern = pattern.toArray(new String[] {});
}
}
}
private static void printParticle(XSParticle particle, String occurs, String absPath, String indent)
{
boolean repeats = particle.isRepeated();
occurs = " MinOccurs = " + particle.getMinOccurs() + ", MaxOccurs = " + particle.getMaxOccurs() + ", Repeats = " + Boolean.toString(repeats);
XSTerm term = particle.getTerm();
if (term.isModelGroup())
{
printGroup(term.asModelGroup(), occurs, absPath, indent);
}
else if(term.isModelGroupDecl())
{
printGroupDecl(term.asModelGroupDecl(), occurs, absPath, indent);
}
else if (term.isElementDecl())
{
printElement(term.asElementDecl(), occurs, absPath, indent);
}
}
private static void printGroup(XSModelGroup modelGroup, String occurs, String absPath, String indent)
{
System.out.println(indent + "[Start of Group " + modelGroup.getCompositor() + occurs + "]" );
for (XSParticle particle : modelGroup.getChildren())
{
printParticle(particle, occurs, absPath, indent + "\t");
}
System.out.println(indent + "[End of Group " + modelGroup.getCompositor() + "]");
}
private static void printGroupDecl(XSModelGroupDecl modelGroupDecl, String occurs, String absPath, String indent)
{
System.out.println(indent + "[GroupDecl " + modelGroupDecl.getName() + occurs + "]");
printGroup(modelGroupDecl.getModelGroup(), occurs, absPath, indent);
}
private static void printComplexType(XSComplexType complexType, String occurs, String absPath, String indent)
{
System.out.println();
XSParticle particle = complexType.getContentType().asParticle();
if (particle != null)
{
printParticle(particle, occurs, absPath, indent);
}
}
private static void printSimpleType(XSSimpleType simpleType, String occurs, String absPath, String indent)
{
SimpleTypeRestriction restriction = new SimpleTypeRestriction();
initRestrictions(simpleType, restriction);
System.out.println(restriction.toString());
}
public static void printElement(XSElementDecl element, String occurs, String absPath, String indent)
{
absPath += "/" + element.getName();
String typeName = element.getType().getBaseType().getName();
if(element.getType().isSimpleType() && element.getType().asSimpleType().isPrimitive())
{
// We have a primitive type - So use that instead
typeName = element.getType().asSimpleType().getPrimitiveType().getName();
}
boolean nillable = element.isNillable();
System.out.print(indent + "[Element " + absPath + " " + occurs + "] of type [" + typeName + "]" + (nillable ? " [nillable] " : ""));
if (element.getType().isComplexType())
{
printComplexType(element.getType().asComplexType(), occurs, absPath, indent);
}
else
{
printSimpleType(element.getType().asSimpleType(), occurs, absPath, indent);
}
}
public static void printNameSpace(XSSchema s, String indent)
{
String nameSpace = s.getTargetNamespace();
// We do not want the default XSD namespaces or a namespace with nothing in it
if(nameSpace == null || Const.schemaNamespace.equals(nameSpace) || s.getElementDecls().isEmpty())
{
return;
}
System.out.println("Target namespace: " + nameSpace);
Iterator<XSElementDecl> jtr = s.iterateElementDecls();
while (jtr.hasNext())
{
XSElementDecl e = (XSElementDecl) jtr.next();
String occurs = "";
String absPath = "";
XSOMNavigator.printElement(e, occurs, absPath,indent);
System.out.println();
}
}
public static void xsomNavigate(File xsdFile)
{
ErrorHandler errorHandler = new ErrorReporter(System.err);
XSSchemaSet schemaSet = null;
XSOMParser parser = new XSOMParser();
try
{
parser.setErrorHandler(errorHandler);
parser.setAnnotationParser(new DomAnnotationParserFactory());
parser.parse(xsdFile);
schemaSet = parser.getResult();
}
catch (Exception exp)
{
exp.printStackTrace(System.out);
}
if(schemaSet != null)
{
// iterate each XSSchema object. XSSchema is a per-namespace schema.
Iterator<XSSchema> itr = schemaSet.iterateSchema();
while (itr.hasNext())
{
XSSchema s = (XSSchema) itr.next();
String indent = "";
printNameSpace(s, indent);
}
}
}
public static void printFile(String fileName)
{
File fileToParse = new File(fileName);
if (fileToParse != null && fileToParse.canRead())
{
xsomNavigate(fileToParse);
}
}
}
And for your Error Reporter use:
import java.io.OutputStream;
import java.io.PrintStream;
import java.text.MessageFormat;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class ErrorReporter implements ErrorHandler {
private final PrintStream out;
public ErrorReporter( PrintStream o ) { this.out = o; }
public ErrorReporter( OutputStream o ) { this(new PrintStream(o)); }
public void warning(SAXParseException e) throws SAXException {
print("[Warning]",e);
}
public void error(SAXParseException e) throws SAXException {
print("[Error ]",e);
}
public void fatalError(SAXParseException e) throws SAXException {
print("[Fatal ]",e);
}
private void print( String header, SAXParseException e ) {
out.println(header+' '+e.getMessage());
out.println(MessageFormat.format(" line {0} at {1}",
new Object[]{
Integer.toString(e.getLineNumber()),
e.getSystemId()}));
}
}
For your main use:
public class WDXSOMParser
{
public static void main(String[] args)
{
String fileName = null;
if(args != null && args.length > 0 && args[0] != null)
fileName = args[0];
else
fileName = "C:\\xml\\CollectionComments\\CollectionComment1.07.xsd";
//fileName = "C:\\xml\\PropertyListingContractSaleInfo\\PropertyListingContractSaleInfo.xsd";
//fileName = "C:\\xml\\PropertyPreservation\\PropertyPreservation.xsd";
XSOMNavigator.printFile(fileName);
}
}
It's agood bit of work depending on how compex your xsd is but basically.
if you had
<Document>
<Header/>
<Body/>
<Document>
And you wanted to find out where were the alowable children of header you'd (taking account of namespaces)
Xpath would have you look for '/element[name="Document"]/element[name="Header"]'
After that it depends on how much you want to do. You might find it easier to write or find something that loads an xsd into a DOM type structure.
Course you are going to possibly find all sorts of things under that elment in xsd, choice, sequence, any, attributes, complexType, SimpleContent, annotation.
Loads of time consuming fun.
Have a look at this.
How to parse schema using XOM Parser.
Also, here is the project home for XOM