2012-02-10 8 views
10

domanda semplificato: Qual è il XPath per selezionare tutti i nodi XML con un attributo che termina con la stringa "Notifica". La prima e la terza nodi in questo frammento:Selezione nodi con XPath per associazione di un sottoinsieme di classi con JAXB

<events> 
    <event name="CreatedNotification" /> 
    <event name="InfoLog" /> 
    <event name="UpdatedNotification" /> 
</events> 

Domanda dettagliata:

voglio selezionare più complexTypes da uno schema XSD per il legame con JAXB. Questo funziona per una singola classe: OrderStateChangeNotification

<jxb:bindings schemaLocation="apiv2.xsd"> 
    <jxb:bindings node="//xs:complexType[@name='OrderStateChangeNotification']"> 
    <inheritance:implements>com.google.checkout.sdk.notifications.Notification</inheritance:implements> 
    </jxb:bindings> 
</jxb:bindings> 

Ecco il frammento di rilevante dal file di schema di schema:

<xs:complexType name="OrderStateChangeNotification"> 
    <xs:all> 
     <xs:element name="new-fulfillment-order-state" type="tns:FulfillmentOrderState" /> 
     <xs:element name="new-financial-order-state" type="tns:FinancialOrderState" /> 
     <xs:element name="previous-fulfillment-order-state" type="tns:FulfillmentOrderState" /> 
     <xs:element name="previous-financial-order-state" type="tns:FinancialOrderState" /> 
     <xs:element name="reason" type="xs:string" minOccurs="0" /> 
     <xs:element name="timestamp" type="xs:dateTime" /> 
     <xs:element name="google-order-number" type="xs:token" /> 
     <xs:element name="order-summary" type="tns:OrderSummary" minOccurs="0" /> 
    </xs:all> 
    <xs:attribute name="serial-number" type="xs:string" use="required" /> 
    </xs:complexType> 

    <xs:complexType name="ChargeAmountNotification"> 
    <xs:all> 
     <xs:element name="timestamp" type="xs:dateTime" /> 
     <xs:element name="latest-charge-amount" type="tns:Money" /> 
     <xs:element name="latest-charge-fee" type="tns:FeeStructure" minOccurs="0" /> 
     <xs:element name="total-charge-amount" type="tns:Money" /> 
     <xs:element name="latest-promotion-charge-amount" type="tns:Money" minOccurs="0" /> 
     <xs:element name="google-order-number" type="xs:token" /> 
     <xs:element name="order-summary" type="tns:OrderSummary" minOccurs="0" /> 
    </xs:all> 
    <xs:attribute name="serial-number" type="xs:string" use="required" /> 
    </xs:complexType> 

Voglio che il legame di applicare a tutti gli oggetti di notifica. Tutti end con "notifica"

Ho provato a cambiare il XPath da

//xs:complexType[@name='OrderStateChangeNotification'] 

a

//xs:complexType[substring(name(), string-length(name()) - 12) = 'Notification'] 

ma non ha funzionato.

Un altro approccio è provare e selezionare tutti i nodi con "riepilogo dell'ordine" e "numero di serie" per i bambini, poiché so che solo gli oggetti di notifica hanno questi.

UPDATE: La soluzione da @Lee Greco Selectes correttamente i nodi che volevo, ma purtroppo, il plugin eredità non è compatibile con più nodi:

[ERROR] XPath evaluation of "//xs:complexType[substring(@name, string-length(@name)-string-length('Notification')+1)='Notification']" results in too many (8) target nodes 

ho finito per enumerare separatamente.

+2

Al fine di sostenere "molteplici nodi", utilizzare il 'multipla = impostazione "true" su ''. Vedi la [discussione qui] (http://java.net/projects/jaxb/lists/users/archive/2011-04/message/11) –

+0

L'ultima voce nella [discussione] (http://java.net/projects/jaxb/lists/users/archive/2011-04/message/11) afferma ancora che non funziona. Ho lo stesso problema e sebbene siano accettate multiple = true e required = false, jaxb soffoca ancora su "La valutazione XPath di" // xs: complexType "risulta in troppi (3) nodi di destinazione" .. – whaefelinger

risposta

5

Con l'espressione

//xs:complexType[substring(name(), string-length(name()) - 12) = 'Notification'] 

stai chiedendo per tutti gli elementi in cui il nome elemento finisce in 'Notifica'. Vuoi davvero chiedere tutti gli elementi con un attributo nome che termina con "Notifica".

Prova a modificare:

//xs:complexType[substring(@name, string-length(@name)-string-length("Notification")+1)="Notification"] 
+1

Questo XPath è corretto , Grazie. Tuttavia, non funziona nel mio contesto perché risulta che il mio plug-in XJC non può accettare query XPath che restituiscono più nodi. Grazie comunque dell'aiuto! –

5

Ho avuto lo stesso problema. Ho scoperto che esisteva un attributo multiple utilizzato da XJC per consentire la corrispondenza di più nodi.

Desidero anche che il binding venga applicato a tutte le posizioni dello schema. xs:anyURI non ha funzionato, ma ho trovato un modo per farlo usando il token *. Ho aggiunto l'attributo required="false" per ignorare schemi che non contengono alcuna corrispondenza.

<jxb:bindings schemaLocation="*"> 
    <jxb:bindings node="//xs:complexType[substring(name(), string-length(name()) - 12) = 'Notification']" multiple="true" required="false"> 
    <inheritance:implements>com.google.checkout.sdk.notifications.Notification</inheritance:implements> 
    </jxb:bindings> 
</jxb:bindings> 

Edit: Ho postato questa risposta senza leggere i commenti della domanda. Perdonami per quello.Sto usando il plugin Maven org.codehaus.mojo:jaxb2-maven-plugin:1.5 con il plugin XJC org.jvnet.jaxb2_commons:jaxb2-basics-project:0.6.4 e sembra funzionare così ...

0

Alla fine ho un problema simile "troppi nodi di destinazione (3)" tuttavia non ho trovato nessuna risposta su nessuno dei i siti ... Pubblicando la soluzione che ho trovato dopo un sacco di tracce ed errori ... L'idea di base per risolvere "troppi nodi di destinazione (3)" è dare XPATH completo del nodo che è multiplo nel tuo XSD.

Qui di seguito è il mio XSD:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="document"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="asset"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="attribute" maxOccurs="unbounded" minOccurs="0"> 
       <xs:complexType> 
        <xs:sequence> 
        <xs:element name="string" minOccurs="0"> 
         <xs:complexType> 
         <xs:simpleContent> 
          <xs:extension base="xs:string"> 
          <xs:attribute type="xs:string" name="value" use="optional"/> 
          </xs:extension> 
         </xs:simpleContent> 
         </xs:complexType> 
        </xs:element> 
        <xs:element name="date" minOccurs="0"> 
         <xs:complexType> 
         <xs:simpleContent> 
          <xs:extension base="xs:string"> 
          <xs:attribute type="xs:string" name="value" use="optional"/> 
          </xs:extension> 
         </xs:simpleContent> 
         </xs:complexType> 
        </xs:element> 
        <xs:element name="array" minOccurs="0"> 
         <xs:complexType> 
         <xs:sequence> 
          <xs:element name="struct" maxOccurs="unbounded" minOccurs="0"> 
          <xs:complexType> 
           <xs:sequence> 
           <xs:element name="field" maxOccurs="unbounded" minOccurs="0"> 
            <xs:complexType> 
            <xs:sequence> 
             <xs:element name="integer" minOccurs="0"> 
             <xs:complexType> 
              <xs:simpleContent> 
              <xs:extension base="xs:string"> 
               <xs:attribute type="xs:byte" name="value"/> 
              </xs:extension> 
              </xs:simpleContent> 
             </xs:complexType> 
             </xs:element> 
             <xs:element name="assetreference" minOccurs="0"> 
             <xs:complexType> 
              <xs:simpleContent> 
              <xs:extension base="xs:string"> 
               <xs:attribute type="xs:string" name="type"/> 
               <xs:attribute type="xs:long" name="value"/> 
              </xs:extension> 
              </xs:simpleContent> 
             </xs:complexType> 
             </xs:element> 
            </xs:sequence> 
            <xs:attribute type="xs:string" name="name" use="optional"/> 
            </xs:complexType> 
           </xs:element> 
           </xs:sequence> 
          </xs:complexType> 
          </xs:element> 
          <xs:element name="integer" minOccurs="0"> 
          <xs:complexType> 
           <xs:simpleContent> 
           <xs:extension base="xs:string"> 
            <xs:attribute type="xs:long" name="value"/> 
           </xs:extension> 
           </xs:simpleContent> 
          </xs:complexType> 
          </xs:element> 
         </xs:sequence> 
         </xs:complexType> 
        </xs:element> 
        <xs:element name="file" minOccurs="0"> 
         <xs:complexType> 
         <xs:simpleContent> 
          <xs:extension base="xs:string"> 
          <xs:attribute type="xs:string" name="name" use="optional"/> 
          </xs:extension> 
         </xs:simpleContent> 
         </xs:complexType> 
        </xs:element> 
        <xs:element name="integer" minOccurs="0"> 
         <xs:complexType> 
         <xs:simpleContent> 
          <xs:extension base="xs:string"> 
          <xs:attribute type="xs:short" name="value"/> 
          </xs:extension> 
         </xs:simpleContent> 
         </xs:complexType> 
        </xs:element> 
        </xs:sequence> 
        <xs:attribute type="xs:string" name="name" use="optional"/> 
       </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
      <xs:attribute type="xs:long" name="id"/> 
      <xs:attribute type="xs:string" name="type"/> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

e sotto è il file di collegamento JAXB, che sta lavorando per sopra XSD:

<bindings xmlns="http://java.sun.com/xml/ns/jaxb" 
      xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      version="2.1"> 
    <bindings schemaLocation= "../assetproduct.xsd" version="1.0"> 
     <!-- Customise the package name 
     <schemaBindings> 
      <package name="com.example.schema"/> 
     </schemaBindings> --> 

     <!-- rename the value element --> 
     <bindings node="//xs:element[@name='document']"> 
      <bindings node="//xs:element[@name='asset']"> 
       <bindings node="//xs:element[@name='attribute']"> 

        <bindings node="//xs:element[@name='string']"> 
         <bindings node=".//xs:attribute[@name='value']"> 
          <property name="ValueAttribute"/> 
         </bindings> 
        </bindings> 


        <bindings node="//xs:element[@name='date']"> 
         <bindings node=".//xs:attribute[@name='value']"> 
          <property name="ValueAttribute"/> 
         </bindings> 
        </bindings> 

        <bindings node="//xs:element[@name='array']"> 

         <bindings node=".//xs:element[@name='struct']"> 
          <bindings node=".//xs:element[@name='field']"> 

           <bindings node=".//xs:element[@name='integer']/xs:complexType"> 
            <bindings node=".//xs:attribute[@name='value']"> 
             <property name="ValueAttribute"/> 
            </bindings> 
           </bindings> 

           <bindings node=".//xs:element[@name='assetreference']"> 
            <bindings node=".//xs:attribute[@name='value']"> 
             <property name="ValueAttribute"/> 
            </bindings> 
           </bindings> 

          </bindings> 
         </bindings> 

        </bindings> 

        <bindings node=".//xs:element[@name='array']/xs:complexType/xs:sequence/xs:element[@name='integer']"> 
          <bindings node=".//xs:attribute[@name='value']"> 
           <property name="ValueAttribute"/> 
          </bindings> 
        </bindings> 

        <bindings node="//xs:element[@name='attribute']/xs:complexType/xs:sequence/xs:element[@name='integer']"> 
         <bindings node=".//xs:attribute[@name='value']"> 
          <property name="ValueAttribute"/> 
         </bindings> 
        </bindings> 
       </bindings> 
      </bindings> 
      </bindings> 
    </bindings> 
</bindings> 
Problemi correlati