2016-12-08 3 views
-2

YAML являетсяАнализировать YAML с космическим именем в JAVA

innings: 
    - 1st innings: 
     team: Australia 
     runs:500 
    - 2nd innings: 
     team: Australia 
     runs:501 

JAVA код:

import java.io.File; 
import java.util.List; 

import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 
import org.apache.commons.lang3.builder.ToStringStyle; 

import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; 

/** 
* Hello world! 
* 
*/ 
public class App { 
    public static void main(String[] args) throws Exception { 
     ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); 
     try { 
      Innings user = mapper.readValue(new File("a.txt"), Innings.class); 
      System.out.println(ReflectionToStringBuilder.toString(user,ToStringStyle.MULTI_LINE_STYLE)); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class Innings { 
    public List<Inning> innings;  
} 
class Inning{ 
    public int runs; 
    public String team; 
} 

ошибок трассировки: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Непризнанный поле «первый innings "(класс Inning), не обозначенный как невежественный (2 известных свойства:," run "," team "]) at [Источник: a.txt; строка: 3, столбец: 7] (через ссылочную цепочку: Innings ["innings"] -> Inning ["1st innings"])

Примечание: Пожалуйста, предложите другой парсер, если jackson здесь не в состоянии помочь.

+2

Просто имейте в виду, что разработчики java чувствуют большую боль, когда видят, что вы сначала называете классы строчными буквами. – Scadge

+0

Или публичные нефинансовые поля в не-частных классах. – Qix

+0

да, я понимаю, на самом деле у меня был тот же класс с тем же именем «Inning», чтобы временно создать этот класс, я сделал еще один класс «inning» – Nitsshukla

ответ

0

Получил это с помощью custom-Deserializer. Спасибо всем.

import java.io.File; 
import java.io.IOException; 
import java.util.List; 

import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 
import org.apache.commons.lang3.builder.ToStringStyle; 

import com.fasterxml.jackson.core.JsonParser; 
import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.DeserializationContext; 
import com.fasterxml.jackson.databind.JsonNode; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.deser.std.StdDeserializer; 
import com.fasterxml.jackson.databind.module.SimpleModule; 
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; 

public class InningsParse { 
    public static void main(String[] args) { 
     ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); 
     SimpleModule module = new SimpleModule(); 
     module.addDeserializer(Inning.class, new InningDeserializer()); 
     mapper.registerModule(module); 
     try { 
      Innings user = mapper.readValue(new File("a.txt"), Innings.class); 
      System.out.println(ReflectionToStringBuilder.toString(user,ToStringStyle.MULTI_LINE_STYLE)); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
class Innings { 
    public List<Inning> innings; 
} 
class Inning{ 
    public int runs; 
    public String team; 
} 
class InningDeserializer extends StdDeserializer<Inning> { 

    public InningDeserializer() { 
     this(null); 
    } 

    public InningDeserializer(Class<?> vc) { 
     super(vc); 
    } 

    @Override 
    public Inning deserialize(JsonParser jp, DeserializationContext ctxt) 
     throws IOException, JsonProcessingException { 
     JsonNode node = jp.getCodec().readTree(jp); 
     String nodeS = node.toString(); 
     nodeS = nodeS.substring(nodeS.indexOf(':')+1, nodeS.toString().lastIndexOf('}')); 
     System.out.println(nodeS); 
     ObjectMapper mapper = new ObjectMapper(); 
     return mapper.readValue(nodeS,Inning.class); 
    } 
} 
0

Я не супер знакомы с YAMLFactory, но если я могу изменить свои POJO, как это:

class innings { 
    public inning[] innings; 
} 
class inning { 
    @JsonProperty("1st innings") 
    public inning_deep first; 

    @JsonProperty("2nd innings") 
    public inning_deep second; 
} 
class inning_deep{ 
    public int runs; 
    public String team; 
} 

кажется десериализовать это нормально, но, очевидно, это, вероятно, не достаточно для вас. Если бы это был JSON, и я бы заменил два свойства inning_deep на массив, и он будет работать нормально. Я думаю, что это ограничение в YAMLFactory и, вероятно, вам нужно будет написать собственный десериализатор.

Возможно, вам будет оказана помощь, открыв проблему here. Пожалуйста, передумайте присвоение класса уважению naming conventions.

Примечание: обычно я бы не пытался опубликовать неполный ответ, но не похоже, что кто-то еще знает, как его исправить.

+0

Большое спасибо за ответ. Да, я хотел получить ответ без жесткого кодирования. Можете ли вы предложить другой синтаксический анализатор, чтобы решить эту проблему? Не имеет значения, даже если это также на Python, Ruby, .NET. Предпочтительно, хотя в JAVA – Nitsshukla