根元素和元素参考名称问题的命名空间
我有几个关于JAXB编组的简单问题。 我试图编组包含以下字段的类:
@XmlElementRef(name = "AlternateVerificationKeys", namespace = "http://schemas.microsoft.com/Azure/MediaServices/KeyDelivery/TokenRestrictionTemplate/v1", type = JAXBElement.class, required = false)
protected JAXBElement<ArrayOfTokenVerificationKey> alternateVerificationKeys;
@XmlElement(name = "Audience", required = true, nillable = true)
@XmlSchemaType(name = "anyURI")
protected String audience;
@XmlElement(name = "Issuer", required = true, nillable = true)
@XmlSchemaType(name = "anyURI")
protected String issuer;
@XmlElement(name = "PrimaryVerificationKey", required = true, nillable = true)
protected TokenVerificationKey primaryVerificationKey;
@XmlElementRef(name = "RequiredClaims", namespace = "http://schemas.microsoft.com/Azure/MediaServices/KeyDelivery/TokenRestrictionTemplate/v1", type = JAXBElement.class, required = false)
protected JAXBElement<ArrayOfTokenClaim> requiredClaims;
@XmlElement(name = "TokenType", required = true)
@XmlSchemaType(name = "string")
protected TokenType tokenType;
并简单地使用以下序列化代码:
public static String asString(JAXBContext pContext, Object pObject) throws JAXBException {
StringWriter sw = new StringWriter();
Marshaller marshaller = pContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.marshal(pObject, sw);
return sw.toString();
}
我得到的输出是:
<TokenRestrictionTemplate xmlns="http://schemas.microsoft.com/Azure/MediaServices/KeyDelivery/TokenRestrictionTemplate/v1">
<ArrayOfTokenVerificationKey>
<TokenVerificationKey
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SymmetricVerificationKey">
<KeyValue></KeyValue>
</TokenVerificationKey>
</ArrayOfTokenVerificationKey>
<Audience>urn:test</Audience>
<Issuer>http://testacs.com/</Issuer>
<PrimaryVerificationKey
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SymmetricVerificationKey">
<KeyValue></KeyValue>
</PrimaryVerificationKey>
<ArrayOfTokenClaim>
<TokenClaim>
<ClaimType>urn:microsoft:azure:mediaservices:contentkeyidentifier</ClaimType>
<ClaimValue
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</TokenClaim>
</ArrayOfTokenClaim>
<TokenType>SWT</TokenType>
</TokenRestrictionTemplate>
现在,这是我面临的问题:
我希望名称空间xmlns:xsi =“http://www.w3.org/2001/XMLSchema-instance”出现在根元素中,即TokenRestrictionTemplate中,而不是单独的子元素。 我怎样才能做到这一点?
我有一些元素,例如带有@XmlElementRef(name =“AlternateVerificationKeys”...)的 JAXBElement ,但是当我编组子元素的名称看起来是ArrayOfTokenVerificationKey而不是AlternateVerificationKeys 。 我怎样才能解决这个问题?
我希望名称空间xmlns:xsi =“http://www.w3.org/2001/XMLSchema-instance”出现在根元素中,即TokenRestrictionTemplate中,而不是单独的子元素。 我怎样才能做到这一点?
这是XML的核心功能。 您可以通过使用从第一个继承的抽象类和多个具体类来实现此目的。 你也应该使用@XmlTransient
和@XmlSeeAlso
来注解抽象类,他们接收具体类的列表。 下面的例子。
1.用这些注释创建一个名为TokenVerificationKey
的抽象类。
@XmlTransient
@XmlSeeAlso({SymmetricVerificationKey.class, X509CertTokenVerificationKey.class})
public abstract class TokenVerificationKey {
}
2. Finnaly,用这些注释来定义具体的类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SymmetricVerificationKey")
public class SymmetricVerificationKey extends TokenVerificationKey {
@XmlElement(name = "KeyValue")
private byte[] keyValue;
}
我有一些元素,例如带有@XmlElementRef(name =“AlternateVerificationKeys”...)的JAXBElement,但是当我编组子元素的名称看起来是ArrayOfTokenVerificationKey而不是AlternateVerificationKeys。 我怎样才能解决这个问题?
您应该使用@XmlElementWrapper
注释TokenRestrictionTemplate.alternateVerificationKeys
以创建集合(包装器)元素和@XmlElement
以设置子元素名称:
@XmlElementWrapper(name = "AlternateVerificationKeys")
@XmlElement(name = "TokenVerificationKey")
private List<TokenVerificationKey> alternateVerificationKeys;
这个设置与前一个设置相结合,产生如下输出。
有了这个技巧,你会得到这个输出:
<TokenRestrictionTemplate xmlns="http://schemas.microsoft.com/Azure/MediaServices/KeyDelivery/TokenRestrictionTemplate/v1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<AlternateVerificationKeys>
<TokenVerificationKey i:type="SymmetricVerificationKey">
<KeyValue>cGVwZXBlZGtkZGllZGpkamRqZGplaWRqZWVpZGplaWRqaWpkZWltZGVpbWRlaWRpZWQ=</KeyValue>
</TokenVerificationKey>
<TokenVerificationKey i:type="X509CertTokenVerificationKey">
<RawBody>MIIDqDCCAxGgAwIBAgIJAMAU1MJasjgBMA0GCSqGSIb3DQEBBQUAMIGVMQswCQYDVQQGEwJBUjENMAsGA1UECBMEQlNBUzENMAsGA1UEBxMEQ0FCQTEXMBUGA1UEChMOU291dGh3b3JrcyBTUkwxGTAXBgNVBAsTEERldmVsb3BtZW50IFVuaXQxCzAJBgNVBAMTAkVWMScwJQYJKoZIhvcNAQkBFhh2ZWNjaGlvZW1hbnVlbEBnbWFpbC5jb20wHhcNMTUwNzE0MTc1MjQ0WhcNMTgwNDEwMTc1MjQ0WjCBlTELMAkGA1UEBhMCQVIxDTALBgNVBAgTBEJTQVMxDTALBgNVBAcTBENBQkExFzAVBgNVBAoTDlNvdXRod29ya3MgU1JMMRkwFwYDVQQLExBEZXZlbG9wbWVudCBVbml0MQswCQYDVQQDEwJFVjEnMCUGCSqGSIb3DQEJARYYdmVjY2hpb2VtYW51ZWxAZ21haWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJC2kNjNnBw2hyyI3Hbu30PRXw17GGfHytyvgB89nuakoFE2Oe7Ic8NDPN5/WeA7MROH7dDKole+MFOjDeSO/8d7ylWieVu08/yVpJwcgM3hV7X9Jbc5Zl0XsMXUxXaLvYAaLb3Kc8LrPPBJtTI2bXesV7AGxYKqcDIpwfQ7BGHwIDAQABo4H9MIH6MB0GA1UdDgQWBBTKcw3CsHdNrjqsOPKCoD+59Nh9ijCBygYDVR0jBIHCMIG/gBTKcw3CsHdNrjqsOPKCoD+59Nh9iqGBm6SBmDCBlTELMAkGA1UEBhMCQVIxDTALBgNVBAgTBEJTQVMxDTALBgNVBAcTBENBQkExFzAVBgNVBAoTDlNvdXRod29ya3MgU1JMMRkwFwYDVQQLExBEZXZlbG9wbWVudCBVbml0MQswCQYDVQQDEwJFVjEnMCUGCSqGSIb3DQEJARYYdmVjY2hpb2VtYW51ZWxAZ21haWwuY29tggkAwBTUwlqyOAEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBVuuFO3cyOPKSE1nvNyshAeRqhRD+igICeCHGP2zpFQ05k4lzRoio/+1/zdkwZ7g1jHSXz+QkGPRjAxMKGoK8huiTvJwJ1jDVNqyJqfnCW4S2AoNCwziKgGriL7luSDZ+PG3MxoNaCB63B6M6OKOezXhFk4VeLJ/NY1Eohe9E1ew==</RawBody>
</TokenVerificationKey>
</AlternateVerificationKeys>
<Audience>http://audience.com</Audience>
<Issuer>https://issuer.com</Issuer>
<PrimaryVerificationKey i:type="SymmetricVerificationKey">
<KeyValue>cGVwZXBlZGtkZGllZGpkamRqZGplaWRqZWVpZGplaWRqaWpkZWltZGVpbWRlaWRpZWQ=</KeyValue>
</PrimaryVerificationKey>
<RequiredClaims>
<TokenClaim>
<ClaimType>urn:microsoft:azure:mediaservices:contentkeyidentifier</ClaimType>
<ClaimValue i:nil="true"/>
</TokenClaim>
</RequiredClaims>
<TokenType>SWT</TokenType>
</TokenRestrictionTemplate>
附加信息:
您可能希望在XML的开头定义一次名称空间。 你应该定义"com.sun.xml.bind.namespacePrefixMapper"
propery。 您还可以设置命名空间的首选前缀。
btw:用于.NET的Azure SDK使用“i”作为前缀。
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
@Override
public String[] getPreDeclaredNamespaceUris() {
return new String[] {
// "http://www.w3.org/2001/XMLSchema-instance"
XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI
};
}
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
// "http://www.w3.org/2001/XMLSchema-instance"
if (namespaceUri.equals(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI)) {
return "i";
}
return suggestion;
}
});
链接地址: http://www.djcxy.com/p/51723.html
上一篇: Namespace for root element & element Ref name issue
下一篇: Remove xsi:type after marshalling abstract class with hierarchy