Combine JAXB and JAXWS for an imported XML Schema - wsdl

How can I specify a JAXB Binding for an imported XSD within a WSDL when using wsimport?
I tried following binding, which causes the error "XPath evaluation of //xs:element[#name='isFoobar'] results in an empty target node".
<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="example.wsdl"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:bindings node="wsdl:definitions">
<jaxws:bindings node="wsdl:types" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
<jaxws:bindings
node="//xs:schema[#targetNamespace='http://www.example.org/']">
<jaxb:globalBindings>
<xjc:serializable uid="10000001" />
</jaxb:globalBindings>
<jaxb:bindings
node="//xs:element[#name='isFoobar']">
<jaxb:typesafeEnumClass name="IsFoobar">
<jaxb:typesafeEnumMember value="01" name="TRUE" />
<jaxb:typesafeEnumMember value="02" name="FALSE" />
</jaxb:typesafeEnumClass>
</jaxb:bindings>
</jaxws:bindings>
</jaxws:bindings>
</jaxws:bindings>
</jaxws:bindings>
Any ideas?

Sorry for the necro-threading, I encountered this problem and although this is one of the first answer that showed up on google with various key word combination it didn't hold the answer I ended up using.
For imported schemas, the easiest way to specify a JAXB binding on an imported XSD within a WSDL is... to treat it as a completely different schema !
Short example :
MyXSD.xsd
<xsd:schema targetNamespace="whatever"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="ThingThatNeedsToBeBound">
<!-- Whatever this is made of -->
</xs:complexType>
</xsd:schema>
No matter where this xsd is imported (wether it's at the root of the of my wsdl or within a nested import), all I need to write to bind my "ThingThatNeedsToBeBound" in my custom binding is :
customBindings.xml
<jaxb:bindings schemaLocation="Path/To/MyXSD.xsd" node="/xs:schema/xs:complexType[#name='ThingThatNeedsToBeBound']">
<!-- your custom binding -->
</jaxb:bindings>
So, it's just like a regular case, except that you specify the schemaLocation, but then you can consider the imported schema as a whole itself instead of a part of something.
I hope this will help others stumbling upon this problem.
Source : http://www.oracle.com/technetwork/articles/grid/jax-ws-jaxb-customization-082750.html
(Note : in the source, the solution seems way more complicated, so my case might have been simpler than what they described, I found my solution using that none the less !)

I did something similar ages ago, I think you need to specify the node to select with XPath as follows:
//xs:element[#name='isFoobar']/xs:complexType
Or replace xs:complexType with whatever kind of type you are using here. Hopefully it will fix your probelm.

My first try at resolving this was trying to somehow use XPath or multiple jxb:binding elements, but that didn't work. As far as I know the XPath just isn't validated properly against imported schemas unless it would all be rewritten and mashed together with DOM.
So the way I resolved this problem was by using inline customizations in the imported XSD. I didn't test this approach with multiple nested imports, but if you got access and time to modify all the imported XSDs this should work out ok. In my opinion this is only necessary if you need to generate the mapping and can be scrubbed/removed from the XSD once the mapping is done.

Related

Does anyone have documentation on CustomActivitiesAndExtensions.xml?

I found this mentioned in a few books I have on TFS2010, but the documentation is pretty sparse, and searching on Google and Bing returns nothing I don't already know.
Does anyone have and detailed information on the using CustomActivitiesAndExtensions.xml and how it works?
The CustomActivitiesAndExtensions.xml file is primarily used to specify additional activities and/or workflow extensions to be loaded by the Build Service to support your build process.
Here's an example:
<?xml version="1.0" encoding="utf-8"?>
<Assemblies DownloadListedItemsOnly="true">
<Assembly LoadListedItemsOnly="true" FileName="CustomAssembly.dll" HostEnvironmentOption="All">
<Activities>
<Activity FullName="CustomAssembly.OnAgentActivity" HostEnvironmentOption="Agent"/>
<Activity FullName="CustomAssembly.OnControllerActivity" HostEnvironmentOption="Controller"/>
<Activity FullName="CustomAssembly.OnBothActivity" HostEnvironmentOption="All"/>
</Activities>
<Extensions>
<Extension FullName="CustomAssembly.OnAgentExtension" HostEnvironmentOption="Agent"/>
<Extension FullName="CustomAssembly.OnControllerExtension" HostEnvironmentOption="Controller"/>
<Extension FullName="CustomAssembly.OnBothExtension" HostEnvironmentOption="All"/>
</Extensions>
</Assembly>
</Assemblies>
The DownloadListedItemsOnly attribute is an optimization you can use to only download the assemblies specified in this file and ignore any others.
Lastly, it's important to note that if you specify an assembly beneath the Activities or Extensions element that doesn't actually have an Activity or Extension (as appropriate) that's discoverable via reflection, then that assembly won't be loaded. The most likely case where this would be a problem would be if you implemented the design-time experience for your activity in a separate assembly.
As you you know TFS based on WF so you just need the documentation of how to create WF custom activity, To create a basic custom activity, you inherit from the Activity class or a derived type. To create a custom composite activity, you inherit from the CompositeActivity class or a derived type.
See this link:
Creating Custom Activities

ws jaxb custom external mapping

I have to do custom JAXB external mapping file.
Already red tutorial about this and can not find any suitable example of JAXB customization. My scenario is that I have two WSDL files main WSDL and secondary WSDL which is included in main one. And in secondary WSDL file is one complexType definition which has a name that I want to customize. BTW name of that complexType is objectFactory. So now you know what I really really need that external customization.
I have came so far that when I run wsimport path-to-my-main-wsdl -b customBindings.jaxb
output is like
[ERROR] XPath evaluation of "//xs:complexType[#name='objectFactory']" results in empty target node
line 2 of file:/customBindings.jaxb
File customBindings.jaxb looks like
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="path-to-my-secondary-wsdl#types?schema1" node="//xs:complexType[#name='objectFactory']">
<jxb:class name="MyObjectFactory" />
</jxb:bindings>
</jxb:bindings>
At second line of my customBindings.jaxb file are two properties schemaLocation and node. Does property schemaLocation need to point at main WSDL or secondary WSDl? And does property node be exact path (XPath) to wanted complexType or is like this ok? And what is with namespaces within XPath (node property), it has to be xs or what? And what actually this types and schema1 stands for in schemaLocation?
thx
I came across your question while researching the same problem.
A few vague hints are found on this page: http://jaxb.java.net/guide/Dealing_with_errors.html
Causes for the "empty target node" message are suggested at the bottom of that page.

MSXML - Namespaces info not persisting

I am using MSXML 6.0 to perform a transform of my own XML into another XML format. I am not sure if I maybe just don't understand exactly how MSXML works, but I believe I have noticed some strange behaviour with it....
I am adding in the namespaces to my XML doc using the setProperty method e.g.
XmlDocument.setProperty('SelectionNamespaces',
' xmlns:ms=''http://mydomain.com/2010/MySchema''');
Then I am building up the XML using my own custom serializer in memory (not saving to disk). Once serialized I then load in the XSLT file and perform the transformation using transformNodeToObject e.g.
AppXmlDoc.transformNodeToObject(XslXmlDoc, AStreamForTransformedXml);
The problem is the transform is working but none of the specific template matching XPath I have in it is. I eliminated any problems with the XSLT file itself by running it with test data through Visual Studio and it worked as expected. I then assumed it must have been an encoding issue so I made sure that all the documents involved were being read/written out as UTF-8....still no luck.
Here is an example of what the transform looks like:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="http://mydomain.com/2010/MySchema" exclude-result-prefixes="ms">
<xsl:template match="/">
<ARoot>
<head>
<xsl:apply-templates select="ms:Element/ms:SubElement" />
</head>
<body>
<xsl:apply-templates select="ms:Element/ms:DifferentSubElement" />
</body>
</ARoot>
So the result of the transform when run through MSXML brings over the basic structure but does not include any of the template data. After some testing I discovered the only way to get it to work is to do it in the following steps:
Create a new XML doc
Set the namespace info using setProperty
Serialize the XML and save to disk.
Close the document - extra step
Create a new Xml doc - extra step
Reload the document - extra step
Re-set the namespace info - extra step
Perform the transform.
So it appears that MSXML loses track of the Namespace information at somepoint. What makes it even more weird is even if you reset the namespace info (after serializing) and try the transform it still doesn't work! It will only seem to work if I save the document, close it and recreate a new XML document and load it back in (which as a consequence I need to reset the namespaces).
Anyone have any thoughts/ideas on this?
The SelectionNamespace property is used for XPath with the selectNodes and selectSingleNode methods, not for XSLT or other purposes. So I am not sure why you set it and what you expect it to help with as you do not seem to use selectNodes or selectSingleNode.
What is it that you want to achieve with MSXML 6? If you want to create some MSXML DOM documents with elements and/or attributes in namespaces then make sure you use createNode as that is the only namespace aware method in MSXML's API.

xmltask confused about dtd

I'm trying to use xmltask for ant to modify a file in a subdirectory:
project/path/to/file.xml
The file refers to a DTD like this:
<!DOCTYPE data SYSTEM "mydtd.dtd">
I don't have the flexibility to change these documents.
This DTD is stored in the same subdirectory, which has always worked fine:
project/path/to/mydtd.dtd
Unfortunately, xmltask is trying to locate the dtd in my project's top-level directory, which is where my build file is located, and where I run from:
[xmltask] java.io.FileNotFoundException: /home/me/project/mydtd.dtd (The system cannot find the file specified)
I see in the xmltask documentation that I can correct this with an xmlcatalog element to tell it where to look up the file. But I need to use a dtd element, and I can only find examples for this element, not documentation; the examples show only a publicId, and if I understand XML correctly this document does not have one. I shouldn't need to specify this, anyway, right, since my document already says my DTD is stored locally and shows right where it is?
Why isn't xmltask finding the DTD correctly? What's the best way to correct or work around this situation?
An XML Catalog is the way to go here, it just needs a bit more perseverance.
As you correctly pointed out, the standard Ant <XmlCatalog> type only allows you to specify public DTD references when using the inline syntax, which is of no use to you. However, <XmlCatalog> also lets you specify a standard OASIS-syntax catalog, which is far richer, including resolving SYSTEM DTD references.
An OASIS catalog (full spec here) looks like this:
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="mydtd.dtd" uri="project/path/to/mydtd.dtd"/>
</catalog>
You can then reference this catalog from the <XmlCatalog>:
<xmlcatalog refid="commonDTDs"/>
<catalogpath>
<pathelement location="path/to/oasis.catalog"/>
</catalogpath>
</xmlcatalog>
And that's that. It's a good idea to build up a reusable OASIS catalog file, and refer to it from various XML-related Ant tasks, all of which can use <XmlCatalog>.
As an alternative, it looks like I can skip the whole validation by creating a blank file with the same name as the DVD file, and then deleting the file when I am done. Odds are I am going to go that route instead of using the catalog.
xmltask isn't finding it because it is looking in the current working directory. Ant allows you to specify a base directory using the basedir attribute of the <target> element. So I suggest you try this:
<target basedir="path/to" ...>
<xmltask...
</target>
It strikes me that it is not the XML/DTD that you really have the problem with, but getting xmltask to interact with the two of them as you want.
If that fails, you could use the Ant Copy task to copy the XML and DTD to the root folder before processing with xmltask, then copying back again.
Have you tried:
<!DOCTYPE data SYSTEM "./path/to/mydtd.dtd">
? Or an absolute path?
Also, you can find <dtd> description here.
I had a similar problem where an XML file had a doctype with SYSTEM reference that could not be changed.
<!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd">
I first went down the road and created a catalog file with the OASIS catalog as described above, but to be able to use external catalogs I had to include the Apache Commons Resolver 1.1 (resolver.jar) in the Ant classpath (see http://ant.apache.org/manual/Types/xmlcatalog.html).
Because I had multiple machines on which this build was supposed to run this seemed overkill, especially since xmltask worked fine if I just removed the doctype definition. I wasn't allowed to remove it permanently because the doctype was needed elsewhere.
Ultimately I used this workaround: I commented out the doctype definition using Ant's replace task, ran the xmltask, and then put the doctype back into the file.
<replace file="myxmlfile.xml">
<replacetoken><!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"></replacetoken>
<replacevalue><!-- !DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd" --></replacevalue>
</replace>
<xmltask .../>
<replace file="${local.opencms.webapp.webinf}/config/opencms-modules.xml">
<replacetoken><!-- !DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd" --></replacetoken>
<replacevalue><!DOCTYPE opencms SYSTEM "http://www.opencms.org/dtd/6.0/opencms-modules.dtd"></replacevalue>
</replace>

Delphi/MSXML: XPath queries fail

I've loaded a XML document, and now I wish to run a XPath query to select a certain subset of the XML. The XML is
<?xml version="1.0"?>
<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications with
XML.</description>
</book>
</catalog>
and the procedure goes something like
procedure RunXPathQuery(XML: IXMLDOMDocument2; Query: string);
begin
XML.setProperty('SelectionLanguage', 'XPath');
NodeListResult := XML.documentElement.selectNodes(Query));
ShowMessage('Found (' + IntToStr(NodeListResult.length) + ') nodes.');
end;
Problem is: when I run the XPath query '/catalog' for the above XML, it returns (as expected) a nodelist of 1 element. However, if I remove :xsi from
<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> and re-run the query, the nodelist returned is empty. If I remove the entire 'xmlns'-attribute, the resulting nodelist has, once again, 1 element.
So my question is this: what can I do to remedy this, i.e. how do I make MSXML return the correct number of instances (when running a XPath query), regardless of the namespace (or other attributes)?
Thanks!
See this link!
When you use <catalog xmlns='http://www.w3.org/2001/XMLSchema-instance'> then the whole node will be moved to a different (default) namespace. Your XPath isn't looking inside this other namespace so it can't find any data. With <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> you're just declaring xsi as a different namespace. This would be a different namespace than the default namespace.
I can't test it right now but adding something like this might help:
XML.setProperty('SelectionNamespaces', 'xmlns=''http://www.w3.org/2001/XMLSchema-instance''');
Or maybe it doesn't. As I said, I can't test it right now.
Figured it out. It seems that my problem has been described here and here (and most likely a zillion other places, too).
The query /*[local-name()='catalog'] works for me.
Use:
document.setProperty('SelectionNamespaces', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
/*[local-name()='catalog']
is a solution to your question.
But why would you want to ignore namespaces? They have been introduced to express something, e.g. to distinguish different types of catalogs. With your query, you can now select the content of any catalog in the world, but I assume you can only handle books. What will happen if you get a catalog of screws or cars instead?
The mentioned things about the prefix (xsi) is correct. If you remove the prefix, all elements are in that namespace (called default namespace then). But you can still deal with it.
In your code, give the namespace a prefix anyway. It needn't even match the original prefix:
XML.setProperty('SelectionNamespaces', "xmlns:xyz='http://www.w3.org/2001/XMLSchema-instance'");
The second thing is to adapt the XPath query. It must then be
/xyz:catalog
The original XML only declares the xsi namespace, but never makes use of it. In this case, you can remove it completely. If you want to use the namespace and you want it with prefixes, then rewrite your XML to
<?xml version="1.0"?>
<xsi:catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<xsi:book id="bk101">
<xsi:author>Gambardella, Matthew</xsi:author>
<xsi:title>XML Developer's Guide</xsi:title>
<xsi:genre>Computer</xsi:genre>
<xsi:price>44.95</xsi:price>
<xsi:publish_date>2000-10-01</xsi:publish_date>
<xsi:description>An in-depth look at creating applications with
XML.</xsi:description>
</xsi:book>
</xsi:catalog>

Resources