2012-10-16 3 views
3

org.simpleframework.xml (http://simple.sourceforge.net/)을 사용하여 Java Objects를 XML로 직렬화합니다.Howto는 결과 XML에 주석을 쓸 annotation을 사용하여 org.simpleframework.xml을 확장합니다.

자바 객체의 주석을 기반으로 결과 XML에 주석 영역을 추가하고 싶습니다.

그래서 예를 들어 내가 좋아하는 몇 가지 자바 객체 작성하려합니다 :

@Root(name = "myclass") 
public class MyClass { 
    @Element(required=true) 
    @Version(revision=1.1) 
    @Comment(text=This Element is new since, version 1.1, it is a MD5 encrypted value) 
    private String activateHash; 
} 

을 그리고 결과 XML과 같을 것이다 : 그 문서의 예 하우투에 있습니다

<myclass version="1.1"> 
    <!-- This Element is new since, version 1.1, it is a MD5 encrypted value --> 
    <activateHash>129831923131s3jjs3s3jjk93jk1</activateHash> 
</myclass> 

가 쓰기 xml에 의견을 쓸 방문자 : http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#intercept

그러나 방문자에게 전략을 전혀 추가하는 방법은 무엇입니까? ?

단순한 프레임 워크의 방문자 개념은 원시 파싱 클래스에 대한 액세스를 허용하지 않습니다. 는 방문자에 덮어 쓰기 만하는 방법이있다 :

public void write(Type type, NodeMap<OutputNode> node) { ... } 

=> OutputNode 나에게 내가 구문 분석하고 요소의 주석을 읽을 수있는 기회를 제공하지 않습니다. 그러면 속성의 주석에 어떻게 액세스해야합니까?

감사합니다. 2012년 11월 5일의 같은

세바스찬

답변

2

업데이트 : org.simpleframework.xml의 저자

답변 : 이

https://simple.svn.sourceforge.net/svnroot/simple/trunk/download/stream/src/test/java/org/simpleframework/xml/strategy/CommentTest.java

package org.simpleframework.xml.strategy; 

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 

import org.simpleframework.xml.Default; 
import org.simpleframework.xml.Root; 
import org.simpleframework.xml.ValidationTestCase; 
import org.simpleframework.xml.core.Persister; 
import org.simpleframework.xml.stream.InputNode; 
import org.simpleframework.xml.stream.NodeMap; 
import org.simpleframework.xml.stream.OutputNode; 

public class CommentTest extends ValidationTestCase { 

    @Retention(RetentionPolicy.RUNTIME) 
    private static @interface Comment { 
     public String value(); 
    } 

    @Root 
    @Default 
    private static class CommentExample { 
     @Comment("This represents the name value") 
     private String name; 
     @Comment("This is a value to be used") 
     private String value; 
     @Comment("Yet another comment") 
     private Double price; 
    } 

    private static class CommentVisitor implements Visitor { 
     public void read(Type type, NodeMap<InputNode> node) throws Exception {} 
     public void write(Type type, NodeMap<OutputNode> node) throws Exception { 
     if(!node.getNode().isRoot()) { 
      Comment comment = type.getAnnotation(Comment.class); 
      if(comment != null) { 
       node.getNode().setComment(comment.value()); 
      } 
     } 
     } 
    } 

    public void testComment() throws Exception { 
     Visitor visitor = new CommentVisitor(); 
     Strategy strategy = new VisitorStrategy(visitor); 
     Persister persister = new Persister(strategy); 
     CommentExample example = new CommentExample(); 

     example.name = "Some Name"; 
     example.value = "A value to use"; 
     example.price = 9.99; 

     persister.write(example, System.out); 
    } 

} 

업데이트로 작동 2012-11-01 20:16

이 원하는 효과를 얻을 것 해결 방법입니다 - 필요한 FieldHelper이 (Get the value of a field, given the hierarchical path)

/** 
    * write according to this visitor 
    */ 
    public void write(Type type, NodeMap<OutputNode> node) { 
     OutputNode element = node.getNode(); 
     Class ctype = type.getType(); 

     String comment = ctype.getName(); 
     if (!element.isRoot()) { 
      FieldHelper fh = new FieldHelper(); 
      element.setComment(comment); 
      try { 
       if (type.getClass().getSimpleName().startsWith("Override")) { 
        type = (Type) fh.getFieldValue(type, "type"); 
       } 
       if (type.getClass().getSimpleName().startsWith("Field")) { 
        Field field = (Field) fh.getFieldValue(type, "field"); 
        System.out.println(field.getName()); 
        Comment commentAnnotation = field.getAnnotation(Comment.class); 
        if (commentAnnotation != null) { 
         element.setComment(commentAnnotation.value()); 
        } 
       } 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
여기

나는이 함께있어 얼마나 멀리에 설명되어 있습니다. 불행히도 예상대로 작동하지 않습니다. XML 용 Simpleframwork의 저자에게 전자 메일을 보냈습니다.

/** 
* get Serializer 
* 
* @return 
*/ 
public Serializer getSerializer() { 
    Serializer serializer = null; 
    Strategy strategy=null; 
    VisitorStrategy vstrategy=null; 
    if ((idname != null) && (refname != null)) { 
     strategy = new CycleStrategy(idname, refname); 
    } 
    CommentVisitor cv=new CommentVisitor(); 
    if (strategy==null) { 
     vstrategy=new VisitorStrategy(cv); 
    } else { 
     vstrategy=new VisitorStrategy(cv,strategy); 
    }  
    serializer = new Persister(vstrategy); 
    return serializer; 
} 
+0

: 방문자는 다음과 같이 가능했던 추가

@Comment("this is the unique identifier") private long id; 

이 같은 후 사용할 수

package com.bitplan.storage.simplexml; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.annotation.ElementType; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Comment { String value(); } 

:

/** * write according to this visitor */ public void write(Type type, NodeMap<OutputNode> node) { OutputNode element = node.getNode(); Class ctype = type.getType(); String comment = ctype.getName(); if (!element.isRoot()) { Comment commentAnnotation = type.getAnnotation(Comment.class); if (commentAnnotation!=null) element.setComment(commentAnnotation.value()); else element.setComment(comment); } } @Override public void read(Type type, NodeMap<InputNode> nodeMap) throws Exception { } } 

는이 같은 주석 주석 선언 감사합니다, 만약 당신이 대답을 공유 할 수 있다면 멋져요 y 나는 얻는다. –

+0

나는 sourceforge 주소가 반송 된 이후에 메일 링리스트에 질문을 넣어야했다.다른 게시물에서 내 Fieldhelper 대답을 upvote하시기 바랍니다 - 그것이 처음 게시했을 때 내 회사의 URL을 가지고 있기 때문에 그것은 편집자에 의해 downvoted되었습니다. –