2016-11-02 43 views
0

我在xsd(http://www.loc.gov/standards/mods/mods.xsd)之外的xjc類的幫助下生成了這些值。現在我想讀取元素的值,例如xml文件(https://www.loc.gov/standards/mods/v3/mods-userguide-examples.html - 第二個示例:數字化書)。我爲這個返回列表或字符串的類(getter方法)動態獲取類和方法。我得到的是屬性的值,而不是元素的值。從MODS模式生成的JAXB未獲取元素的值

我的類:解組

import java.io.File; 
import java.util.List; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Unmarshaller; 

public class XMLToObject { 

    /** 
    * 
    * @return List of mods definitions from xml file 
    */ 
    public static List convert() { 
     try { 
      JAXBContext jaxbContext = JAXBContext.newInstance(ModsCollectionDefinition.class); 
      Unmarshaller u = jaxbContext.createUnmarshaller(); 

      File f = new File("test.xml"); 
      ModsCollectionDefinition test = (ModsCollectionDefinition)((javax.xml.bind.JAXBElement) u.unmarshal(f)).getValue(); 
      return test.getMods(); 
     } catch (JAXBException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 

類用於處理XML數據

import java.lang.reflect.*; 
import java.util.List; 
import org.example.mods.XMLToObject; 
/** 
* Operations on XML data 
*/ 
public class MODS { 
    private static List xmlData = XMLToObject.convert(); 
    public static StringBuilder stringBuilder = new StringBuilder(); 

    /** 
    * 
    * Get the whole content of the xml file 
    * 
    * @return String 
    */ 
    public String getXML() { 
     if(xmlData != null) { 
      processClass(xmlData); 
      xmlData = null; 
     } else { 
      stringBuilder.append("No file imported!"); 
     } 
     return stringBuilder.toString(); 
    } 

    /** 
    * 
    * @param list from which will be derived class type 
    */ 
    private void processClass(List list) { 
     for (int i = 0; i < list.size(); i++) { 
      Class current = castDynamic(list.get(i)); 
      try { 
       Method[] methods = current.getMethods(); 
       if (methods.length > 0) { 
        for (int j = 0; j < methods.length; j++) { 
         if (checkIfMethodReturnsString(methods[j]) && !methods[j].getName().contains("toString")) { 
          callMethodWhichReturnsString(methods[j], list.get(i)); 
         } else if (checkIfMethodReturnsList(methods[j])) { 
          callMethodWhichReturnsList(methods[j], list.get(i)); 
         } 
        } 
       } 
      } catch (NullPointerException e) { 
       stringBuilder.append("No methods in this class!"); 
      } 
     } 
    } 

    /** 
    * 
    * @param object from which will be derived class 
    * @return Class 
    */ 
    private Class castDynamic(Object object) { 
     String className = object.getClass().getName(); 
     try { 
      Class cls = Class.forName(className); 
      cls.cast(object); 
      return cls; 
     } catch (ClassNotFoundException e) { 
      return null; 
     } 
    } 

    /** 
    * 
    * @param method of the class 
    * @return String 
    */ 
    private String getMethodType(Method method) { 
     return method.getReturnType().getName(); 
    } 

    /** 
    * 
    * @param method which will be checked according to return type 
    * @return boolean 
    */ 
    private boolean checkIfMethodReturnsString(Method method) { 
     if(getMethodType(method).contains("String")) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    /** 
    * 
    * @param method which will be checked according to return type 
    * @return boolean 
    */ 
    private boolean checkIfMethodReturnsList(Method method) { 
     if(getMethodType(method).contains("List")) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    /** 
    * 
    * 
    * @param method which is invoked 
    * @param obj on which method is invoked 
    */ 
    private void callMethodWhichReturnsList(Method method, Object obj) { 
     try { 
      List list = (List) method.invoke(obj); 
      processClass(list); 
     } catch (IllegalAccessException | InvocationTargetException ex) { 
      stringBuilder.append("Invoke exception!"); 
     } 
    } 

    /** 
    * Method returns strings which are attributes but doesn't return values of the elements! 
    * 
    * @param method which is invoked 
    * @param obj on which method is invoked 
    */ 
    private void callMethodWhichReturnsString(Method method, Object obj) { 
     try { 
      stringBuilder.append(obj.getClass().getSimpleName().replace("Definition", "")); 
      stringBuilder.append(" - "); 
      stringBuilder.append(method.getName().replace("get", "")); 
      stringBuilder.append(": "); 
      stringBuilder.append(method.invoke(obj)); 
     } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException ex) { 
      stringBuilder.append("Invoke exception!"); 
     } 
    } 
} 

的屬性輸出:

<mods version="3.3"> 

MODS的 - 版本:3.3

輸出的元件:

<titleInfo> 
    <title>At Gettysburg, or, What a Girl Saw and Heard of the Battle: A True Narrative</title> 
</titleInfo> 

TitleInfo - 類型:空 TitleInfo - 機關:空 TitleInfo - ID:空 TitleInfo - 腳本:空 TitleInfo - 的ContentType:空 TitleInfo - 作用:空 TitleInfo - 用法:初級 TitleInfo - 標題:空 TitleInfo - OTHERTYPE:空 TitleInfo - 提供:是 TitleInfo - 音譯:空 TitleInfo - NameTitleGroup:空 TitleInfo - AltRepGroup:空 TitleInfo - TypeBinded:簡單 TitleInfo - AltFormat:空 TitleInfo - 的DisplayLabel:空 TitleInfo - HREF:空 TitleInfo - Arcrole:空 TitleInfo - 顯示:空 TitleInfo - Actuate的:空 TitleInfo - 郎鹹平:空 TitleInfo - LangBinded:空 TitleInfo - AuthorityURI:空 TitleInfo - ValueURI:空

生成的類TitleInfoDefinition:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "titleInfoDefinition", propOrder = { 
    "titleOrSubTitleOrPartNumber" 
}) 
public class TitleInfoDefinition { 

    @XmlElementRefs({ 
     ....... 
     @XmlElementRef(name = "title", namespace = "http://www.loc.gov/mods/v3", type = JAXBElement.class, required = false), 
     ...... 
    }) 
    protected List<Object> titleOrSubTitleOrPartNumber; 
    ...... 
    @XmlAttribute(name = "title", namespace = "http://www.w3.org/1999/xlink") 
    protected String title; 
    ..... 

    * <p> 
    * Objects of the following type(s) are allowed in the list 
    * {@link JAXBElement }{@code <}{@link StringPlusLanguage }{@code >} 
    * {@link JAXBElement }{@code <}{@link StringPlusLanguage }{@code >} 
    * {@link JAXBElement }{@code <}{@link StringPlusLanguage }{@code >} 
    * {@link JAXBElement }{@code <}{@link StringPlusLanguage }{@code >} 
    * {@link NonSort } 
    * 
    * 
    */ 
    public List<Object> getTitleOrSubTitleOrPartNumber() { 
     if (titleOrSubTitleOrPartNumber == null) { 
      titleOrSubTitleOrPartNumber = new ArrayList<Object>(); 
     } 
     return this.titleOrSubTitleOrPartNumber; 
    } 

    ...... 

    /** 
    * Ruft den Wert der title-Eigenschaft ab. 
    * 
    * @return 
    *  possible object is 
    *  {@link String } 
    *  
    */ 
    public String getTitle() { 
     return title; 
    } 
    ....... 
} 

我試圖讓直接將此值:

((JAXBElement)((TitleInfoDefinition)test).getTitleOrSubTitleOrPartNumber().get(0)).getValue(); 

輸出繼電器: [email protected]

((JAXBElement)((TitleInfoDefinition)test).getTitleOrSubTitleOrPartNumber().get(0)).getName() 

輸出繼電器: {標題

我如何獲得標題元素的價值?

回答

1

當您獲得StringPlusLanguage類實例時,對應於您的title元素。這是一個複雜的類型與模式中的簡單內容:

<xs:complexType name="stringPlusLanguage"> 
    <xs:simpleContent> 
     <xs:extension base="xs:string"> 
      <xs:attributeGroup ref="languageAttributeGroup"/> 
     </xs:extension> 
    </xs:simpleContent> 
</xs:complexType> 

所以你可能有一個屬性像contentvalue,檢查類和訪問此屬性。這將包含元素的文本值。

title不僅僅是字符串的原因正是因爲它在模式中被建模爲複雜類型。如果它本來是xs:string,那麼你會得到一個字符串值屬性。