Java 简单XML引用解析
我提出Jaxb问题的最初原因是什么 我无法在使用简单框架时遇到同样的问题: 今天,我得到了与持久化调用有关的内容,这些内容与我的Jaxb问题中的内容相同: 我得到的是副本,而不是参考资料。我再次寻找一个解决方案与适当的参考。这次是简单XML框架 这里的示例的基类“modelement”与另一个问题中的Person不同。否则问题也是一样的 我再次调用解组器两次,以获取pass1中的所有ID,并使用从PASS2中创建的查找HashMap中收集的结果 获得适当参考的解决方案是什么?我的假设是添加一个回调函数,它实际上允许被调用函数修改解组结果(请参阅了解包装方法) 将实现这一点(与我同时发布的JaxB解决方案相当) 此代码来自ModelElementSimpleXmlImpl基类:Java 简单XML引用解析,java,unmarshalling,simple-framework,Java,Unmarshalling,Simple Framework,我提出Jaxb问题的最初原因是什么 我无法在使用简单框架时遇到同样的问题: 今天,我得到了与持久化调用有关的内容,这些内容与我的Jaxb问题中的内容相同: 我得到的是副本,而不是参考资料。我再次寻找一个解决方案与适当的参考。这次是简单XML框架 这里的示例的基类“modelement”与另一个问题中的Person不同。否则问题也是一样的 我再次调用解组器两次,以获取pass1中的所有ID,并使用从PASS2中创建的查找HashMap中收集的结果 获得适当参考的解决方案是什么?我的假设是添加一
protectedstring-ref;
/**
*xsd的getter:string/string-id
*@returnid
*/
@org.simpleframework.xml.Attribute(name=“ref”,required=false)
公共字符串getRef(){
返回ref;
}
/**
*xsd的setter:string/string-id
*@param pid-id的新值
*/
@org.simpleframework.xml.Attribute(name=“ref”,required=false)
公共void setRef(字符串pRef){
ref=pRef;
}
私有布尔调试=true;
/**
*显示调试信息
*@param title
*@param-key
*@param我
*@param已找到
*/
public void showDebug(找到字符串标题、字符串键、ModelElementSimpleXmlImpl me、ModelElementSimpleXmlImpl){
字符串deref=“?”;
如果(找到!=null)
deref=“->”+found.getId()+”(“+found.getClass().getSimpleName()+”);
如果(调试)
System.err.println(title+“:“+key+”(“+me.getClass().getSimpleName()+”)“+deref+”-“+this);
}
/**
*跟踪已经看到的元素
*/
公共静态映射查找=新建HashMap();
@证实
public void validate(){
ModelElementSimpleXmlImpl me=此;
String key=me.getId();
if(key!=null){
showDebug(“id”,key,me,null);
查找。放置(键,me);
}
key=me.getRef();
if(key!=null){
if(lookup.containsKey(键)){
modelementsimplexmlimpl meRef=lookup.get(键);
showDebug(“ref”、key、me、meRef);
me.setRef(null);
me.copyFrom(meRef);
}否则{
如果(调试)
showDebug(“ref”,me.getRef(),me,null);
}
}
}
尼尔·加拉赫建议:
使用CycleStragy之类的工具应该相当容易。只需创建MyCycleStrategy,如果出现“无效引用”异常,只需返回null并记住引用。拾取所有ID和值后,再进行第二次传递。在第二个过程中,将该值分配给ref或id的第一个匹配项。然后,所有以下引用都应被赋予相同的值。这应该行得通
他是对的。以下延长周期策略按照建议工作:
/**
* Two Path Cycle Strategy
*
* @author wf
*
*/
public static class TwoPathCycleStrategy extends CycleStrategy {
String id;
String ref;
public static boolean debug = false;
/**
* create a twoPath Cycle Strategy
*
* @param id
* @param ref
*/
public TwoPathCycleStrategy(String id, String ref) {
super(id, ref);
this.id = id;
this.ref = ref;
}
/**
* show debug information
*
* @param title
* @param key
* @param value
*/
public void showDebug(String title, String key, Value value) {
if (debug) {
String id = "?";
Object v = value;
while ((v instanceof Value) && ((Value) v).isReference()) {
v = ((Value) v).getValue();
}
if (v == null) {
id = "null";
} else {
// FIXME - adapt to your code or comment out
//if (v instanceof ModelElement) {
// ModelElement me = (ModelElement) v;
// id = me.getId();
//}
}
System.err.println(title + ":" + key + "->"
+ v.getClass().getSimpleName() + ":"
+ value.getType().getSimpleName() + ":" + value.isReference() + ":"
+ id);
}
}
public Map<String, Value> lookup = new HashMap<String, Value>();
@SuppressWarnings("rawtypes")
@Override
public Value read(Type type, NodeMap node, Map map) throws Exception {
Value value = null;
Node refNode = node.get(ref);
Node keyNode = node.get(id);
try {
value = super.read(type, node, map);
if (keyNode != null) {
String key = keyNode.getValue();
if (value != null) {
showDebug("id", key, value);
lookup.put(key, value);
} else {
showDebug("id?", key, value);
}
}
} catch (CycleException ce) {
if (ce.getMessage().contains("Invalid reference")) {
if (refNode != null) {
String key = refNode.getValue();
if (lookup.containsKey(key)) {
value = lookup.get(key);
showDebug("ref", key, value);
} else {
showDebug("ref?",key,null);
}
}
} else {
throw ce;
}
}
return value;
}
}
/**
*双路径循环策略
*
*@author wf
*
*/
公共静态类TwoPathCycleStategy扩展了CycleStategy{
字符串id;
字符串引用;
公共静态布尔调试=false;
/**
*创建双路径循环策略
*
*@param-id
*@param-ref
*/
公共TwoPathCycleStategy(字符串id,字符串引用){
super(id,ref);
this.id=id;
this.ref=ref;
}
/**
*显示调试信息
*
*@param title
*@param-key
*@param值
*/
public void showDebug(字符串标题、字符串键、值){
如果(调试){
字符串id=“?”;
对象v=值;
while((v instanceof Value)和((Value)v).isReference()){
v=((值)v).getValue();
}
如果(v==null){
id=“null”;
}否则{
//修改代码或注释
//if(v instanceof modelement){
//modelement me=(modelement)v;
//id=me.getId();
//}
}
System.err.println(title+“:“+key+”->”
+v.getClass().getSimpleName()+“:”
+value.getType().getSimpleName()+“:”+value.isReference()+“:”
+身份证);
}
}
publicmap lookup=newhashmap();
@抑制警告(“原始类型”)
@凌驾
公共值读取(类型类型、节点映射节点、映射映射)引发异常{
Value=null;
Node refNode=Node.get(ref);
Node keyNode=Node.get(id);
试一试{
value=super.read(类型、节点、映射);
if(keyNode!=null){
字符串key=keyNode.getValue();
if(值!=null){
showDebug(“id”、键、值);
lookup.put(键、值);
}否则{
showDebug(“id?”,键,值);
}
}
}捕获(循环异常ce){
if(ce.getMessage()包含(“无效引用”)){
if(refNode!=null){
String key=refNode.getValue();
if(lookup.containsKey(键)){
value=lookup.get(键);
showDebug(“ref”、键、值);
}否则{
showDebug(“ref?”,key,null);
}
}
}否则{
投掷ce;
}
}
返回值;
}
}
protected String ref;
/**
* getter for xsd:string/String id
* @return id
*/
@org.simpleframework.xml.Attribute(name="ref",required=false)
public String getRef() {
return ref;
}
/**
* setter for xsd:string/String id
* @param pid - new value for id
*/
@org.simpleframework.xml.Attribute(name="ref",required=false)
public void setRef(String pRef) {
ref=pRef;
}
private boolean debug=true;
/**
* show debug information
* @param title
* @param key
* @param me
* @param found
*/
public void showDebug(String title,String key,ModelElementSimpleXmlImpl me, ModelElementSimpleXmlImpl found) {
String deref="?";
if (found!=null)
deref="->"+found.getId()+"("+found.getClass().getSimpleName()+")";
if (debug)
System.err.println(title+": "+key+"("+me.getClass().getSimpleName()+")"+deref+" - "+this);
}
/**
* keep track of the elements already seen
*/
public static Map<String,ModelElementSimpleXmlImpl> lookup=new HashMap<String,ModelElementSimpleXmlImpl>();
@Validate
public void validate() {
ModelElementSimpleXmlImpl me=this;
String key=me.getId();
if (key!=null) {
showDebug("id",key,me,null);
lookup.put(key, me);
}
key=me.getRef();
if (key!=null) {
if (lookup.containsKey(key)) {
ModelElementSimpleXmlImpl meRef=lookup.get(key);
showDebug("ref",key,me,meRef);
me.setRef(null);
me.copyFrom(meRef);
} else {
if (debug)
showDebug("ref",me.getRef(),me,null);
}
}
}
/**
* Two Path Cycle Strategy
*
* @author wf
*
*/
public static class TwoPathCycleStrategy extends CycleStrategy {
String id;
String ref;
public static boolean debug = false;
/**
* create a twoPath Cycle Strategy
*
* @param id
* @param ref
*/
public TwoPathCycleStrategy(String id, String ref) {
super(id, ref);
this.id = id;
this.ref = ref;
}
/**
* show debug information
*
* @param title
* @param key
* @param value
*/
public void showDebug(String title, String key, Value value) {
if (debug) {
String id = "?";
Object v = value;
while ((v instanceof Value) && ((Value) v).isReference()) {
v = ((Value) v).getValue();
}
if (v == null) {
id = "null";
} else {
// FIXME - adapt to your code or comment out
//if (v instanceof ModelElement) {
// ModelElement me = (ModelElement) v;
// id = me.getId();
//}
}
System.err.println(title + ":" + key + "->"
+ v.getClass().getSimpleName() + ":"
+ value.getType().getSimpleName() + ":" + value.isReference() + ":"
+ id);
}
}
public Map<String, Value> lookup = new HashMap<String, Value>();
@SuppressWarnings("rawtypes")
@Override
public Value read(Type type, NodeMap node, Map map) throws Exception {
Value value = null;
Node refNode = node.get(ref);
Node keyNode = node.get(id);
try {
value = super.read(type, node, map);
if (keyNode != null) {
String key = keyNode.getValue();
if (value != null) {
showDebug("id", key, value);
lookup.put(key, value);
} else {
showDebug("id?", key, value);
}
}
} catch (CycleException ce) {
if (ce.getMessage().contains("Invalid reference")) {
if (refNode != null) {
String key = refNode.getValue();
if (lookup.containsKey(key)) {
value = lookup.get(key);
showDebug("ref", key, value);
} else {
showDebug("ref?",key,null);
}
}
} else {
throw ce;
}
}
return value;
}
}