The XPath expression in my external binding files can't target the elements in my XML schemas which are imported into my WSDL.
Everything runs if I do inline binding customization but I really wanted to have external binding files that way I never accidentally overwrite(refresh) the files containing my customizations.
The start of my binding file:
<jaxb:bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
version="2.1">
<jaxb:bindings schemaLocation="../wsdl/localhost_7001/ExampleSessionBean/ExampleSessionBeanService.wsdl#types?schema1">
<jaxb:bindings node="//xs:schema[#targetNamespace='urn:myExample']">
My WSDL contains:
<types>
<xsd:schema>
<xsd:import namespace="urn:myExample" schemaLocation="http://localhost:7001/ExampleSessionBean/ExampleSessionBeanService?xsd=1"/>
</xsd:schema>
<xsd:schema>
<xsd:import namespace="http://ejbs/" schemaLocation="http://localhost:7001/ExampleSessionBean/ExampleSessionBeanService?xsd=2"/>
</xsd:schema>
</types>
No matter what I do XPath can't find anything in the xsd:import'ed schemas. The error I get is:
[ERROR] XPath evaluation of "//xs:schema[#targetNamespace='urn:myExample']" results in empty target node
I've tried accessing the xs:schema by index number instead of the namespace and that doesn't work either. It seems like my XPath expressions can't reach elements from imported schemas...is there anyway to fix this?
This is a Java SE 7 project being developed under NetBean 7.2. I'm using NetBeans to do all my wsimport stuff if that matters but the command output looks fairly standard for RI/Metro.
EDIT:
I figured out that I can get an external binding file to work if I use SCD. This XPath example doesn't work:
<bindings node="//xsd:schema[#targetNamespace='urn:myExample']">
<bindings node="//xs:complexType[#name='myType']">
<class name="MyClass"/>
</bindings>
</bindings>
But this SCD example does.
<bindings scd="x-schema::tns" xmlns:tns="urn:myExample">
<bindings scd="~tns:myType">
<class name="MyClass"/>
</bindings>
</bindings>
Is this a known thing where XPath doesn't work in xjb files when using wsimport but SCD does?
you should use it like:
<jaxws:bindings node="wsdl:definitions/wsdl:types/xsd:schema[#targetNamespace='http://duke.example.org']">
<jaxb:schemaBindings>
<jaxb:package name="fromwsdl.server"/>
</jaxb:schemaBindings>
</jaxws:bindings>
Be careful with the namespaces
It all is explained here:
https://jax-ws.java.net/nonav/2.1.2/docs/customizations.html
You could compile each of the XML schemas to Java classes individually. Then you can leverage episode files so that the generated classes can be used when you compile schemas that import that XML schema.
Below is an example of how you produce an episode file.
xjc -b binding1.xml -episode common.episode common.xsd
And below is an example of how you consume and episode file. The episode file is just a JAXB external bindings file and therefore is specified using the -b flag.
xjc -d out main.xsd -extension -b common.episode
For More Information
http://blog.bdoughan.com/2011/12/reusing-generated-jaxb-classes.html
For new people, you can simply use two binding files, one applied to wsdl and other applied to the schema by using the -b option of wsdl2java cxf code generation class accepts multiple binding files:
<java classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
<arg value="-d"/>
<arg value="${src}"/>
<arg value="-b"/>
<arg value="${wsdl.home}\jaxws-bindings.xml"/>
<arg value="-b"/>
<arg value="${wsdl.home}\jaxb-bindings.xml"/>
<arg value="${wsdl.home}\YOUR_WSDL.wsdl"/>
<classpath>
<path refid="cxf.classpath"/>
</classpath>
</java>
Content of file 'jaxws-bindings.xml':
<jaxws:bindings wsdlLocation="YOUR_WSDL.wsdl"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
</jaxws:bindings>
Content of 'jaxb-bindings.xml':
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
jaxb:version="2.0">
<jaxb:bindings schemaLocation="ManagePartyCustomerDataManagement_PARTY_G7-IOP_In_1.0.xsd">
<jaxb:bindings node="//xsd:element[#name='eventDate']">
<jaxb:javaType name="java.util.Date"
parseMethod="com.sofrecom.gaia.ebs.provider.utils.jaxb.StringDateAdapter.parseDate"
printMethod="com.sofrecom.gaia.ebs.provider.utils.jaxb.StringDateAdapter.printDate" />
</jaxb:bindings>
Adding this section to my JAXB configuration helped to do away with a similar error:
<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:enableWrapperStyle>true</jaxws:enableWrapperStyle>
<jaxws:enableAsyncMapping>false</jaxws:enableAsyncMapping>
</jaxws:bindings>
Complete configuration:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="2.1"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:enableWrapperStyle>true</jaxws:enableWrapperStyle>
<jaxws:enableAsyncMapping>false</jaxws:enableAsyncMapping>
</jaxws:bindings>
<jaxb:bindings schemaLocation="ContactService.wsdl" node="/wsdl:definitions/wsdl:types/xs:schema">
<jaxb:schemaBindings>
<jaxb:package name="za.org.kuali.kfs.sys.integration.iapi.contactservice"/>
</jaxb:schemaBindings>
</jaxb:bindings>
</jaxb:bindings>
Credits:
https://stackoverflow.com/a/7890753/315385
https://stackoverflow.com/a/38077750/315385
Related
I want to protect against incorrect case being placed within a parameter in a nant script.
I want to take the value of x and convert it to lower case, I tried using
string::to-lower()
but that did not work hoping someone has come across this and has a simple solution.
<?xml version="1.0" encoding="utf-8"?>
<project name="test" Default="test" value="net-4.0" >
<property name="x" value="default" unless="${property::exists('x')}"/>
<target name="test">
<echo message="${x}" />
</target>
</project>
UPDATE
I tried the suggestion put forward by Yan with the code below this still outputs capitals I will explain further
I have a nant script that has a parameter that can be passed into it, a property checks for the existence of the parameter and if it exists it uses it, if not there is a default value. I want to take the parameter in whatever form it is given and convert it to lower case while still checking for its existence.
<?xml version="1.0" encoding="utf-8"?>
<property overwrite="true" name="x" value="default" unless="${property::exists('x')}"/>
<property overwrite="true" name="x" value="${string::to-lower(x)}" />
<target name="test">
<echo message="${x}" />
</target>
</project>
I believe this to be the way you think I should do it Yan. I have tested this with the following command line arguments.
nant -buildfile:nant.build test -D:x=TEST
This produces the output
Target framework: Microsoft .NET Framework 4.0
Target(s) specified: test
[property] Read-only property "x" cannot be overwritten.
test:
[echo] TEST
BUILD SUCCEEDED - 0 non-fatal error(s), 1 warning(s)
Total time: 0.1 seconds.
any solution would be much appreciated
When you say parameter, so you mean its name or its value? ie, do you want to ensure x is lowercase, or test (I assume the latter)? If I have the following nant script:
<?xml version="1.0" encoding="utf-8"?>
<project name="test" Default="test" value="net-4.0" >
<property overwrite="false" name="x" value="default"/>
<property overwrite="false" name="x_internal" value="${string::to-lower(x)}" />
<target name="test">
<echo message="${x_internal}" />
</target>
</project>
And call it like this:
nant.exe -buildfile:nant.build test -D:x=TESTx
nant.exe -buildfile:nant.build test -D:X=TESTX
I receive the following response:
Target framework: Microsoft .NET Framework 4.0
Target(s) specified: test
test:
[echo] testx
BUILD SUCCEEDED
Total time: 0 seconds.
Target framework: Microsoft .NET Framework 4.0
Target(s) specified: test
test:
[echo] default
BUILD SUCCEEDED
Total time: 0 seconds.
Is this what you are after?
UPDATE
I think this is what is tripping you up:
Note: properties set on the command-line are always read-only.
(From section 4 in the NAnt Properties documentation)
The function you mentioned should work. See if you spelled the syntax correctly:
<echo message="${string::to-lower(x)}" />
I've a wsdl (I dont have the .xsd file) and I want to generate the classes from it.
Using wsimport I get a tree of classes that is the standard mapping of the webservice schemas itself and of its dependencies.
I obtain something like com->(microsoft,mycompany), org->(apache).
However I need to remap the package com.mycompany and all the classes inside into com.mycompany.test.
So I've tried to use the option of -b of ws import creating a a docbinding.xml that is Schema Customization XML. The content is :
<jxb:bindings version="2.1" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings node="wsdl:definitions/wsdl:types/xsd:schema[#targetNamespace='http://mycompany.com/test/']">
<jaxb:package name="com.mycompany.test"/>
</jxb:bindings>
</jxb:bindings>
launching wsimport with this syntax :
wsimport -p com.mycompany -b docbinding.xml https://mycompany.com/nicews/test.svc?wsdl
I obtain a initial error that stops the generation of the classes:
[ERROR] XPath error: null
...
How can I fix the binding XML ?
If the types are in seperate XSD files. This is the way to do it.
Create two configuration files.
wsdl.jxb
<?xml version="1.0" encoding="UTF-8"?>
<jaxws:bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="https://mycompany.com/nicews/test.svc?wsdl"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
<jaxws:package name="com.mycompany.wsdl"/> <!-- namespace what you want here -->
</jaxws:bindings>
xsds.jxb
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="2.1"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<!-- This is used becuase we don't need to differentiate between absent and nil elements, you may want to differentiate. If so, remove this binding -->
<jaxb:globalBindings generateElementProperty="false">
<xjc:simple />
</jaxb:globalBindings>
<!-- REPEAT THIS SECTION FOR EACH XSD, replacing schemaLocation and package with whatever you want -->
<jaxb:bindings
schemaLocation="http://mycompany.com/someWsdlIncludeLocation?xsd=xsd0"
node="/xs:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.mycompany.dto.saml" />
</jaxb:schemaBindings>
</jaxb:bindings>
<!-- END SECTION -->
</jaxb:bindings>
Create a batch file in the same directory
rmdir /S /Q build
rmdir /S /Q dist
rmdir /S /Q src
mkdir build
mkdir dist
mkdir src
"%JAVA_HOME%\bin\wsimport.exe" -b wsdl.jxb -b xsds.jxb -s src -d build -keep http://mycompany.com/someWSDLlocation?wsdl
"%java_home%\bin\jar" cf dist/mycompanyClient.jar -C build/ .
"%java_home%\bin\jar" cf dist/mycompanyClient-src.jar -C src/ .
See if that works for you. Make sure to edit the JXB files appropriately for your wsdl/xsd locations, and packages you want.
i try to generate classes using JAXB but I a get an exception :
IllegalArgumentException: Illegal pattern character 'g'
I'using a complex XSD file and a binding file as below.
Can somebody give a clue to where investigate ?
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="IFX170_XSD.xsd" node="/xs:schema">
<jxb:schemaBindings>
<jxb:package name="cy.com.netinfo.netteller.ifx"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings schemaLocation="RemitDetail_Type.xsd" node="/xs:schema">
<jxb:schemaBindings>
<jxb:package name="cy.com.netinfo.netteller.ifx.remitdetailinfo"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings schemaLocation="$pain.001.001.01.xsd" node="/xs:schema">
<jxb:schemaBindings>
<jxb:package name="cy.com.netinfo.netteller.ifx.swift.pain_001_001_1"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings schemaLocation="$pain.002.001.01.xsd" node="/xs:schema">
<jxb:schemaBindings>
<jxb:package name="cy.com.netinfo.netteller.ifx.swift.pain_002_001_1"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings schemaLocation="$pain.004.001.01.xsd" node="/xs:schema">
<jxb:schemaBindings>
<jxb:package name="cy.com.netinfo.netteller.ifx.swift.pain_004_001_1"/>
</jxb:schemaBindings>
</jxb:bindings>
At last I found the answer.
The problem is due to a mistake in the class Options in the package com.sun.tools.xjc.
In the method getPrologComment the class builds a localized message taking parameter fot date and time from a localized resource bundle, but then formats the date using a fixed Locale.ENGLISH. This behavior is inside JAXB 2.2.6.
I solved the problem simply updating the file MessageBundle_it.properties (in my case for italian) in the package com\sun\tools\xjc\ of the jar file jaxb-xjc.jar.
The changes I made was :
Driver.DateFormat = aaaa.MM.gg (original) to Driver.DateFormat = yyyy/MM/dd (new) and
Driver.TimeFormat = hh:mm:ss a z (original) to Driver.TimeFormat = HH:mm:ss (new)
With those changes I was able to generate the classes as needed.
HTH
Flavio
I have same error generating java objects form command line xjc.bat. You can solve adding option -no-header
I might guess that one of your xsd files have a regexp-based restriction attached to a type/element. Have you validated those files?
I run the following command
java -jar "C:\Program Files\eclipse\plugins\org.jvnet.jaxbw.eclipse_1.1.0\lib\jaxb-xjc.jar" -d src -catalog xsd\catalog.cat xsd\componentsData.xsd
xsd\componentsData.xsd contain the following lines:
xmlns:txtColor="com.my.company.product.jaxb.TextColor"
xmlns="com.my.company.product.jaxb.componentsData"
targetNamespace="com.my.company.product.jaxb.componentsData"
<xsd:import
schemaLocation="TextColor.xsd"
namespace="com.my.company.product.jaxb.TextColor"/>
xsd\TextColor.xsd contain the following
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
xmlns="com.my.company.product.jaxb.TextColor"
targetNamespace="com.my.company.product.jaxb.TextColor"
>
this is my catalog:
<!DOCTYPE catalog
PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN"
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system
systemId="com.my.company.product.jaxb.TextColor.TextColor.xsd"
uri="TextColor"/>
and my files got generated in the following path - THE ORDER IS INVERTED WHY ?:
componentsData.jaxb.product.company.my.com
and
TextColor.jaxb.product.company.my.com
if i add the following argument files got generated in the right order but the catalog.cat don't seem to be taken in consideration
-p com.my.company.product.jaxb.componentsData
I needed to add a binding file (-b option with xjc)
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
version="2.1">
<jaxb:bindings schemaLocation="componentsData.xsd" node="/xsd:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.my.company.product.jaxb.componentsData"/>
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="TextColor.xsd" node="/xsd:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.my.company.product.jaxb.TextColor"/>
</jaxb:schemaBindings>
</jaxb:bindings>
</jaxb:bindings>
But i still have a question:
I Started using xjc because i didn't succeed doing it with eclipse, how can i do it with eclipse gui
I was hoping to find a way to set a value in my csproj file during my build to a value. Is there a task in MSBuild that I can use to set a property permanently to a value? In the example below, can I set CustomValue = Yes permanently?
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
.....
<CustomValue>XXXX</CustomValue
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids></ProjectTypeGuids>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
You can use the XmlPoke task to do that. It seems a little odd to be altering projects this way though. Alternatively, you can set up a tiny import file,
<!-- in your main project file, right below the PropertyGroup -->
<Import
Condition="Exists('Custom.props')"
Project="Custom.props"
/>
Then dynamically create this property file, as,
<?xml version="1.0" encoding="utf-8"?>
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
ToolsVersion="4.0">
<PropertyGroup>
<CustomValue>True</CustomValue>
</PropertyGroup>
</Project>
You can either use XmlPoke on just this .props file, or use WriteLinesToFile to create the entire file. This secondary file wouldn't need to be checked into source control, the condition on the import makes the project functional when the file doesn't exist.
The XmlPoke task would look like this,
<XmlPoke
XmlInputPath="./Custom.props"
Namespaces="<Namespace Prefix='x'
Uri='http://schemas.microsoft.com/developer/msbuild/2003'/>"
Query="//x:PropertyGroup/x:CustomValue/#Value"
Value="True"
/>