Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using DOM and XPath to Navigate Xsd

Status
Not open for further replies.

YerMom

Programmer
Oct 3, 2006
127
0
0
US
I want to use the classes in javax.xml.xpath to navigate XSDs.

I have an XSD with the following structure:

Code:
<?xml version="1.0" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="[URL unfurl="true"]http://www.mycompany.com"[/URL] xmlns:tns="[URL unfurl="true"]http://www.mycompany.com"[/URL] xmlns:xs="[URL unfurl="true"]http://www.w3.org/2001/XMLSchema">[/URL]

<xs:complexType name="MyOperation">
    <xs:sequence>
      <xs:element name="input" type="tns:MyOperationInputMessage" form="qualified" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

<xs:complexType name="MyOperation2">
    <xs:sequence>
      <xs:element name="input" type="tns:MyOperation2InputMessage" form="qualified" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

</xs:schema>

This xsd sample is incomplete to keep things simple.

Given an operation name such as "MyOperation" (which will be variable) I need to navigate to the "MyOperation" xs:complextype element and get the value of the "type" attribute of the enclosed xs:element element

Here is a start at what I think I need to do:

Code:
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true); 

DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(fileName);
XPath xpath = XPathFactory.newInstance().newXPath();

String opName = "MyOperation";
String attrib = "[@name=".concat("'").concat(opName).concat("'").concat("]");
XPathExpression expr = xpath.compile("/xs:schema/xs:complexType".concat(attrib));
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;

It's very clear I'm lost and this is a guess so I need your help.

Can anyone tell me the correct way to get the value of the "type" attribute of the enclosed xs:element?

Thanks very much.
 
I'm not familiar with XPath. If the structure is always the same, I'd go

Code:
doc.getElementbyId("MyOperation").getFirstChild().getFirstChild().getNodeType()

You can also check the XML Forum.

Cheers,
Dian
 
[1] If you want to use namespace prefix, you have to implement the NameContext interface that I see no sign of you having one.

[1.1] In that context, the xpath "expression" looks like this and the type attribute is directly returned. You can apply getNodeValue() to it to retrieve the value.
[tt]
String expression="/xs:schema/xs:complexType[@name='" + opName + "/xs:sequence/xs:element[@name='input']/@type";
[/tt]
You see you seem to miss out quite a bit.

[2] Without implementing the NameContext interface, you can make the NamespaceAware XPath to get the result too. Only this time, you have make heavy use of xpath built-in function. The expression look like this.
[tt]
String expression="/*[local-name()='schema' and namespace-uri()='[ignore][/ignore]']" +
"/*[local-name()='complexType' and namespace-uri()='[ignore][/ignore]' and @name='" + opName + "']" +
"/*[local-name()='sequence' and namespace-uri()='[ignore][/ignore]']"+
"/*[local-name()='element' and namespace-uri()='[ignore][/ignore]' and @name='input']" +
"/@type";
[/tt]
[2.1] You can then apply it directly to what you have got already without doing further consideration of implementing NamespaceContext.
 
Amendment
I missed out a closing bracket in [1.1] that the line should be read like this.
[tt] String expression="/xs:schema/xs:complexType[@name='" + opName + "[red]'][/red]/xs:sequence/xs:element[@name='input']/@type";
[/tt]
 
Thanks Dianecht and tsuji.

Dianect -- I need to learn XPath, but thanks for your insight and recommendation of the XML forum.

Tsuji -- Thanks for the detail. I think I'll try implementing the NameContext interface. I've done some preliminary reading on how it can be done but I need to study it more, and do additional reading on namespaces.

Hopefully you'll get notifications for additional postings I'll do on this thread.

Thanks.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top