How does jaxb determine the list of namespace prefix declarations whem marshalling an object? I used xjc to compile java classes for ebics (ebics schema). When I create an instance for an ebicsRequest it looks like this:
<?xml version="1.0" encoding="UTF-16"?>
<ns2:ebicsRequest xmlns:ns2="http://www.ebics.org/H003" Revision="1" Version="H003" xmlns="http://www.ebics.org/H003" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ns4="http://www.ebics.org/S001" xmlns:ns5="http://www.ebics.org/H000">
<ns2:header authenticate="true">
<ns2:static>
<ns2:HostID>SIZBN001</ns2:HostID>
<ns2:Nonce>A5488F43223063171CA0FA59ADC635F0</ns2:Nonce>
<ns2:Timestamp>2009-08-04T08:41:56.967Z</ns2:Timestamp>
<ns2:PartnerID>EBICS</ns2:PartnerID>
<ns2:UserID>EBIX</ns2:UserID>
<ns2:Product Language="de">EBICS-Kernel V2.0.4, SIZ/PPI</ns2:Product>
<ns2:OrderDetails>
<ns2:OrderType>FTB</ns2:OrderType>
<ns2:OrderID>A037</ns2:OrderID>
<ns2:OrderAttribute>OZHNN</ns2:OrderAttribute>
<ns2:StandardOrderParams/>
</ns2:OrderDetails>
<ns2:BankPubKeyDigests>
<ns2:Authentication Algorithm="RSA" Version="X002">...</ns2:Authentication>
<ns2:Encryption Algorithm="RSA" Version="E002">...</ns2:Encryption>
</ns2:BankPubKeyDigests>
<ns2:SecurityMedium>0000</ns2:SecurityMedium>
<ns2:NumSegments>1</ns2:NumSegments>
</ns2:static>
<ns2:mutable>
<ns2:TransactionPhase>Initialisation</ns2:TransactionPhase>
</ns2:mutable>
</ns2:header>
<ns2:AuthSignature>
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#xpointer(//*[@authenticate='true'])">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>CSbjPbiNcFqSl6lCI1weK5x1nMeCH5bTQq5pedq5uI0=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
</ns2:AuthSignature>
<ns2:body>
<ns2:DataTransfer>
<ns2:DataEncryptionInfo authenticate="true">
<ns2:EncryptionPubKeyDigest Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" Version="E002">dFAYe281vj9NB7w+VoWIdfHnjY9hNbZLbHsDOu76QAE=</ns2:EncryptionPubKeyDigest>
<ns2:TransactionKey>...</ns2:TransactionKey>
</ns2:DataEncryptionInfo>
<ns2:SignatureData authenticate="true">...</ns2:SignatureData>
</ns2:DataTransfer>
</ns2:body>
</ns2:ebicsRequest>
I have used a custom NamespacePrefixMapper
to declare the default namespace and prefixes for ds and xsi. For the namespace ds it works fine. But for the default namespace it does not. It is declared two times once as ns2 and once as "" the latter coming from my custom NamespacePrefixMapper.getPreDeclaredNamespaceUris
. I have played around a lot with this class. Also I tried to use the package-info.java
but I was not able to make jaxb use "http://www.ebics.org/H003"
as default namespace. What I also do not understand is the appearance of ns4 and ns5 which are not at all part of the xml document.
My NamespacePrefixMapper class looks like
public class NamespacePrefixMapperImpl extends NamespacePrefixMapper implements NamespaceContext {
private static final String[] EMPTY_STRING = new String[0];
private Map prefixToUri = null;
private Map uriToPrefix = null;
private void init(){
prefixToUri = new HashMap();
prefixToUri.put("", "http://www.ebics.org/H003" );
prefixToUri.put("ds", "http://www.w3.org/2000/09/xmldsig#" );
prefixToUri.put("xsi", "http://www.w3.org/2001/XMLSchema-instance" );
prefixToUri.put(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI );
prefixToUri.put(XMLConstants.XMLNS_ATTRIBUTE , XMLConstants.XMLNS_ATTRIBUTE_NS_URI );
uriToPrefix = new HashMap();
for(String prefix : prefixToUri.keySet()){
uriToPrefix.put(prefixToUri.get(prefix), prefix);
}
}
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if (uriToPrefix == null)
init();
if (uriToPrefix.containsKey(namespaceUri)){
return uriToPrefix.get(namespaceUri);
}
return suggestion;
}
@Override
public String[] getContextualNamespaceDecls() {
// TODO Auto-generated method stub
return EMPTY_STRING;
}
@Override
public String[] getPreDeclaredNamespaceUris() {
// TODO Auto-generated method stub
return EMPTY_STRING;
}
@Override
public String[] getPreDeclaredNamespaceUris2() {
return new String [] {"", prefixToUri.get("")};
}
public String getNamespaceURI(String prefix) {
if (prefixToUri == null)
init();
if (prefixToUri.containsKey(prefix)) {
return prefixToUri.get(prefix);
} else {
return XMLConstants.NULL_NS_URI;
}
}
public String getPrefix(String namespaceURI) {
if (uriToPrefix == null)
init();
if (uriToPrefix.containsKey(namespaceURI)){
return uriToPrefix.get(namespaceURI);
} else {
return null;
}
}
public Iterator getPrefixes(String namespaceURI) {
if (uriToPrefix == null)
init();
List prefixes = new LinkedList();
if (uriToPrefix.containsKey(namespaceURI)){
prefixes.add(uriToPrefix.get(namespaceURI));
}
return prefixes.iterator();
}
}
I am using
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0-b64 (Sun Microsystems Inc.)
Specification-Title: Java Architecture for XML Binding
Specification-Version: 2.0
Specification-Vendor: Sun Microsystems, Inc.
Implementation-Title: JAXB Reference Implementation
Implementation-Version: 2.0.2
Implementation-Vendor: Sun Microsystems, Inc.
Implementation-Vendor-Id: com.sun
Extension-Name: com.sun.xml.bind
Build-Id: b01
Class-Path: jaxb-api.jar activation.jar jsr173_1.0_api.jar jaxb1-impl.
jar
Name: com.sun.xml.bind.v2.runtime
Implementation-Version: 2.0.2-b01-fcs
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…