2013-12-17 5 views
2

Мне нужно проанализировать XML-файл и создать кучу объектов с ArrayList с отражением.Как обойти метод Class.forName()

Я достиг этого с Class.forName().

Вот мой код:

public ArrayList<Sweets> parse(String fileName) throws Exception { 

    File file = new File(fileName); 
    Document doc = builder.parse(file); 

    ArrayList<Sweets> items = new ArrayList<Sweets>(); 
    int itemCount = Integer.parseInt(path 
      .evaluate("count(/gift/item)", doc)); 

    for (int i = 1; i <= itemCount; i++) { 

     double sugar = Double.parseDouble(path.evaluate("/gift/item[" + i + "]/@sugar", doc)); 
     String name = path.evaluate("/gift/item[" + i + "]/name", doc); 
     double weight = Double.parseDouble(path.evaluate("/gift/item[" + i 
       + "]/weight", doc)); 

     Class cl = Class.forName("com.epam.lab.model.chocolate." + name); 
     items.add((Sweets) cl.getConstructor(double.class, double.class) 
       .newInstance(sugar, weight)); 
    } 

    return items; 
} 

Он работает, но на этой линии:

Class cl = Class.forName("com.epam.lab.model.chocolate." + name); 

Но некоторые недостатком является то, что этот метод должен иметь полное имя класса включают в себя пакеты.

Требуется только от отдельной упаковки. Но мне нужно брать другие классы из другого места. Ограничение forName() не позволяет мне это делать.

Как обходить Class.forName() ограничений?

+3

"rescission"? Вы имели в виду ... «отражение»? –

+0

Вы можете попробовать несколько пакетов, или вы можете использовать https://code.google.com/p/reflections/, который индексирует и ищет классы для вас. –

ответ

3

Существует хорошая альтернатива чтению и анализу XML в объекты Java: JAXB с аннотациями.

Чтение по:

MyDoc doc = load(MyDoc.class, "/mydoc.xml"); 

private <T> T load(Class<T> klazz, String xmlResource) { 
    try { 
     JAXBContext jaxbContext = JAXBContext.newInstance(klazz); 
     return klazz.cast(jaxbContext.createUnmarshaller() 
       .unmarshal(getClass().getResourceAsStream(xmlResource))); 
    } catch (JAXBException e) { 
     Logger.getLogger(getClass().getName()).log(Level.SEVERE, 
       "Cannot read resource " + xmlResource, e); 
     throw new IllegalStateException(e); 
    } 
} 

@XmlRootElement(name="document") 
public class MyDoc { 

    @XmlElement(name="sweetsList") 
    public List<Sweets> sweets= new ArrayList<>(); 
} 

<document> 
    <sweetsList> 
     ... 
    </sweetsList> 
</document> 

И те же аннотации с @XmlElement и @XmlAttribute для других классов.

+0

вы можете порекомендовать хороший учебник по jaxb? –

+0

JAXB со временем превратился во что-то простое. Поэтому мне трудно дать указатели. Перед аннотациями для XML-структуры была определена .xsd, схемы в XML. Я обнаружил, что больше ошибок, чем аннотации. Возможно, IDE может предоставить поддержку, IDE NetBeans, IntelliJ IDEA, плагин eclipse +. Удачи вам в ваших исследованиях. –

0

Я боюсь, что это невозможно - для создания экземпляра вам необходимо предоставить полное квалифицированное имя класса.

Но, возможно, вы можете предоставить дополнительную информацию в разобранном xml - например. часть названия пакета, которая отличается между типами сладостей?

String name = path.evaluate("/gift/item[" + i + "]/name", doc); 
String type = path.evaluate("/gift/item[" + i + "]/type", doc); 
double weight = Double.parseDouble(path.evaluate("/gift/item[" + i + "]/weight", doc)); 
Class cl = Class.forName("com.epam.lab.model" + type + "." + name); 

Или, если формат XML запечатан, то, возможно, вы можете создать отображение между отдельными сладостями именами и пакетами classess, которые представляют их?

Смежные вопросы