2009-12-30 1 views
22

예를 들어 다른 스키마를 가져 오는 간단한 스키마가 있습니다. 두 번째 스키마 (urn : just : attributes, just-attributes.xsd)는 단지 속성 그룹을 정의합니다.String에 정렬 할 때 JAXB가 사용하는 네임 스페이스 접두어를 사용자 정의 할 수 있습니까?

<?xml version="1.0" encoding="UTF-8"?> 
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/MySchema" 
    xmlns:tns="http://www.example.org/MySchema" 
    elementFormDefault="qualified" 
    xmlns:ja="urn:just:attributes"> 

    <import schemaLocation="just-attributes.xsd" namespace="urn:just:attributes"/> 

    <element name="MyElement"> 
     <complexType> 
      <attributeGroup ref="ja:AttributeGroup"/> 
     </complexType> 
    </element> 
</schema> 

저는이 스키마에서 클래스를 생성하기 위해 Metro xjc Ant 태스크를 사용하고 있습니다. 내가 겪고있는 문제는 내가 상호 작용하고있는 써드 파티 애플리케이션이 네임 스페이스에 특유하다는 것입니다. 이 경우 String 값이 필요하므로 serialize해야합니다. 나는 이것을 위해 상용구 코드를 사용한다. 나에게

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns2:MyElement xmlns:ns1="urn:just:attributes" xmlns:ns2="http://www.example.org/MySchema" ns1:attrib1="1234" ns1:attrib2="5678"/> 

내가 가진 문제의 라인을 따라 뭔가를 제공

private static <T> String marshal(T object) throws JAXBException{ 
    OutputStream outputStream = new ByteArrayOutputStream(); 
    JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass()); 
    Marshaller marshaller = jaxbContext.createMarshaller(); 
    marshaller.marshal(object, outputStream); 
    return outputStream.toString(); 
} 

이 타사는, 그들이 이름에 따라 구문 분석하는 말을하는 것입니다 xmlns:thirdpartyns="urn:just:attributes" 같은 무언가를 기대한다는 것입니다 네임 스페이스에 주어진다. 이 소프트웨어가 작동하려면 "thirdpartyns"가되어야합니다.

결과 문자열에서 찾기 및 바꾸기가 부족하다는 점을 알고있는 사람이 있습니까? 아마도 사용자 지정 바인딩 규칙을?

답변

26

http://hwellmann.blogspot.com/2011/03/jaxb-marshalling-with-custom-namespace.html

이 그것을 수행하는 방법을 보여줍니다.

또 다른 : 연결이 너무 죽는 경우 http://www.systemmobile.com/?p=280

키 비트 :

com.sun.xml.bind.marshaller 패키지에있는 NamespacePrefixMapper의 클래스. 추상 클래스가 구현하는 하나 개의 방법이있다 : 당신은 또한 javax.xml.xpath.XPath를 사용하는 경우 다음

public abstract String getPreferredPrefix( 
    String namespaceUri,   
    String suggestion,   
    boolean requirePrefix); 

Marshaller marshaller =   
    jaxbContext.createMarshaller();   
marshaller.setProperty(”com.sun.xml.bind.namespacePrefixMapper”,   
    new MyNamespacePrefixMapper()); 

을, 당신 같이 NamespacePrefixMapper도 javax.xml.namespace.NamespaceContext을 구현할 수 있습니다 네임 스페이스 사용자 정의를 단일 클래스로 중앙 집중화합니다.

+0

감사합니다. 이것은 매력처럼 작동합니다! –

+0

링크가 끊어졌습니다. –

+0

링크가 죽었습니다 ... @DaveC 그것을 확인하십시오! – basZero

0

NamespacePrefixMapper이라는 내부 JAXB 구현 클래스를 사용하는 방법이 있습니다. JAXB RI에서는 com.sun.xml.bind.marshaller이지만 Java6에서는 com.sun.xml.internal.bind.marshaller입니다.

이 클래스는 네임 스페이스 URI를 접두사에 매핑하는 추상 메소드를 서브 클래스 화하고 구현할 수있는 추상 클래스입니다. 속성 이름이 Java6 버전에 대해 서로 다른 될 것입니다

JAXBContext context = ... 
Marshaller marshaller = context.createMarshaller(); 
NamespacePrefixMapper prefixMapper = new MyPrefixMapperImpl(); 
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", prefixMapper); 

,하지만 당신은 아이디어를 얻을 :

그런 다음 마샬에 그 서브 클래스의 인스턴스를 주입.

이것은 내부 JAXB 구현 클래스이므로, 향후 버전에서이를 보장 할 수는 없습니다.

+1

'internal' 클래스를 서브 클래스 화하지 마십시오. – Barett

11

자바 SE6that 테스트하며 (above 바와 같은) 자바 SE 5 용액에 비해 작은 변화가 필요

Marshaller m = context.createMarshaller(); 
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
    m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); 
    m.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", mapper); 

따라서 위에서 세번째 재산권 추가 .internal.에 포함 패키지 이름은 Java SE5 버전과 비교됩니다. 아직 알지 못했던 것은 Marshaller에게 어떤 네임 스페이스 URI가 기본 네임 스페이스 ("")가되는지 알려주는 방법입니다. getPreferredPrefix() 메서드를 오버라이드하고 빈 문자열을 반환하면 Marshaller는 기본 네임 스페이스의 특성을 쓰는 데 문제가 있습니다 (이 경우 ns1이라는 새 네임 스페이스가 생성됩니다).

+2

명백히 자바 SE 7에서는 "com.sun.xml.bind.namespacePrefixMapper"를 다시 사용합니다 ... (예외를 얻는 Java SE 6 속성 사용) – edbras

+2

Java SE에 대한 올바른 방법을 알고있는 사람이 있습니까? 8? @edbras – basZero

5

동일한 질문이 있습니다. package-info.java (없으면 수동으로 만들 수 있습니다.)

@javax.xml.bind.annotation.XmlSchema(xmlns = { 
     @javax.xml.bind.annotation.XmlNs(namespaceURI = "urn:just:attributes", prefix = "thirdpartyns") }, 
     elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
+1

xsd에서 소스를 생성하면 어떻게됩니까? 아파치 플러그인 메이븐 사용하기. 이 방법으로 사용자 정의 할 수 있습니까? –

관련 문제