2017-03-23 113 views
0

我試圖獲取在我的XSD中在xs:complexType中聲明的元素的註釋。這樣的元素是SchemaPreperty類型。但是,與SchemaGlobalElement和SchemaType不同,我不能使用SchemaProperty.getAnnotation()XMLBeans:獲取嵌套元素的註釋

這是XSD。我需要訪問元素number的文檔。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="test" type="my-test-type" /> 

    <xs:complexType name="my-test-type"> 
     <xs:sequence> 
      <xs:element name="number" "xs:int"> 
       <xs:annotation> 
        <xs:documentation>This is the documentation I need.</xs:documentation> 
       </xs:annotation> 
      </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

我該怎麼做?這似乎不......可能。

回答

1

所以我在XMLBeans FAQ中找到了答案。這裏的link

我粘貼FAQ的代碼,因爲只包含鏈接的答案是不被接受的。你幾乎可以弄清楚如何將它從這個例子適應自己的需要:

public static void someMethod() { 
    SchemaType t = XmlBeans.getContextTypeLoader().findType(new QName("http://test", "T")); 
    SchemaProperty[] schemaProperties = t.getProperties(); 
    for (int i = 0; i < schemaProperties.length; i++) 
     printPropertyInfo(schemaProperties[i]); 

    System.out.println(); 

    if (t.getContentType() == SchemaType.ELEMENT_CONTENT || 
      t.getContentType() == SchemaType.MIXED_CONTENT) 
    { 
     SchemaParticle topParticle = t.getContentModel(); 
     // topParticle is non-null if we checked the content 
     navigateParticle(topParticle); 
    } 
} 

public static void navigateParticle(SchemaParticle p) 
{ 
    switch (p.getParticleType()) 
    { 
    case SchemaParticle.ALL: 
    case SchemaParticle.CHOICE: 
    case SchemaParticle.SEQUENCE: 
     // These are "container" particles, so iterate over their children 
     SchemaParticle[] children = p.getParticleChildren(); 
     for (int i = 0; i < children.length; i++) 
      navigateParticle(children[i]); 
     break; 
    case SchemaParticle.ELEMENT: 
     printElementInfo((SchemaLocalElement) p); 
     break; 
    default: 
     // There can also be "wildcards" corresponding to <xs:any> elements in the Schema 
    } 
} 

public static void printPropertyInfo(SchemaProperty p) 
{ 
    System.out.println("Property name=\"" + p.getName() + "\", type=\"" + p.getType().getName() 
     + "\", maxOccurs=\"" + 
     (p.getMaxOccurs() != null ? p.getMaxOccurs().toString() : "unbounded") + "\""); 
} 

public static void printElementInfo(SchemaLocalElement e) 
{ 
    System.out.println("Element name=\"" + e.getName() + "\", type=\"" + e.getType().getName() 
     + "\", maxOccurs=\"" + 
     (e.getMaxOccurs() != null ? e.getMaxOccurs().toString() : "unbounded") + "\""); 
    SchemaAnnotation annotation = e.getAnnotation(); 
    if (annotation != null) 
    { 
     SchemaAnnotation.Attribute[] att = annotation.getAttributes(); 
     if (att != null && att.length > 0) 
      System.out.println(" Annotation: " + att[0].getName() + "=\"" + 
       att[0].getValue() + "\""); 
    } 
} 

至於屬性的FAQ甚至沒有提到他們,但他們訪問不同。這讓我非常頭痛,因爲我試圖弄清楚如何訪問屬性的註釋,類似於上面的代碼。訪問屬性的註釋非常簡單直接。

這裏是我這樣做的當前方法:

public String getAttributeAnnotation(SchemaType t, String attributeLocalName) { 
    if (null != t) { 
     SchemaAttributeModel attrModel = t.getAttributeModel(); 
     if (null != attrModel) { 
      SchemaLocalAttribute[] attributes = t.getAttributeModel().getAttributes(); 
      if (attributes.length > 0) { 
       SchemaLocalAttribute attr = Arrays.stream(attributes) 
         .filter(a -> a.getName().getLocalPart().equals(attributeLocalName)) 
         .findFirst().orElse(null); 
       if (null != attr) { 
        String annotationDoc = getAnnotationDocumentation(attr.getAnnotation()); 
        return annotationDoc; 
       } 
      } 
     } 
    } 

    return null; 
} 

這裏是我的getAnnotationDocumentation()(這可以改進!)。您可以使用它來檢索元素和屬性的xs:annotation中的xs:documentation。

public static String getAnnotationDocumentation(SchemaAnnotation an) { 
    if (null != an) { 
     StringBuilder sb = new StringBuilder(); 
     XmlObject[] userInformation = an.getUserInformation(); 
     if (null != userInformation & userInformation.length > 0) { 
      for (XmlObject obj : userInformation) { 
       Node docInfo = obj.getDomNode(); 
       NodeList list = docInfo.getChildNodes(); 
       for (int i = 0; i < list.getLength(); i++) { 
        Node c = list.item(i); 
        if (c.getNodeType() == Node.TEXT_NODE) { 
         String str = c.getNodeValue(); 
         sb.append(str.trim()); 
         break; 
        } 
       } 
      } 
     } 
     return sb.toString(); 
    } 
    return null; 
} 
+0

用於解釋方案的XMLBeans文檔非常差。此代碼工作,它讀取聲明爲類型定義的子項的註釋。不幸的是,它不會讀取在元素處直接聲明的註釋(如果它們使用類型定義或不)。 – Gio