2012-02-10 15 views
10

Pytanie uproszczone: Co to jest XPath, aby wybrać wszystkie węzły XML z atrybutem, który kończy się ciągiem "Powiadomienie". Pierwsze i trzecie węzły w tym fragmencie:Wybieranie węzłów z XPath do wiązania podzbioru klas za pomocą JAXB

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

Szczegółowe Pytanie:

Chcę zaznaczyć kilka complexTypes od schematu XSD dla wiązania z JAXB. To działa dla jednej klasy: 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> 

Oto odnośny fragment z pliku schematu schematu:

<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> 

chcę wiążący stosuje się do wszystkich obiektów powiadomień. Wszyscy kończą się z "zgłoszenie"

Próbowałem zmieniając XPath z

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

do

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

ale to nie działa.

Innym podejściem jest próba wybrania wszystkich węzłów z "podsumowaniem zamówienia" i "numerem seryjnym" dzieci, o ile wiem, że mają je tylko te obiekty powiadomień.

UPDATE: Rozwiązanie przez @Lee Greco poprawnie selectes węzły chciałem, ale niestety, wtyczka dziedziczenie nie jest kompatybilny z wieloma węzłami:

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

skończyło się tylko wyliczając je oddzielnie.

+2

W celu wsparcia "wielu węzłów", użyj 'wielokrotność = "true" ustawienie na ''. Zobacz [dyskusja tutaj] (http://java.net/projects/jaxb/lists/users/archive/2011-04/message/11) –

+0

Ostatni wpis w [dyskusji] (http://java.net/projects/jaxb/lists/users/archive/2011-04/message/11) nadal stwierdza, że ​​nie działa. Mam ten sam problem i mimo że akceptowane są multiple = true i required = false, jaxb nadal dusi się o "Ocena XPath" "// xs: complexType" daje zbyt wiele (3) docelowych węzłów ". – whaefelinger

Odpowiedz

5

Z wypowiedzi

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

jesteś prośbą o wszystkich elementach, gdzie nazwa elementem kończy się „powiadomienie”. Naprawdę chcesz poprosić o wszystkie elementy z atrybutem nazwy, który kończy się na "Powiadomieniu".

Spróbuj to zamiast:

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

Ta XPath jest poprawna , dzięki. Nie działa to jednak w moim kontekście, ponieważ okazuje się, że moja wtyczka XJC nie może akceptować zapytań XPath, które zwracają wiele węzłów. Dzięki za pomoc! –

5

miałem ten sam problem. Dowiedziałem się, że istnieje atrybut multiple, który został użyty przez XJC, aby umożliwić dopasowanie wielu węzłów.

Chciałem również, aby powiązanie miało zastosowanie do każdej lokalizacji schematu. xs:anyURI nie działa, ale znalazłem sposób, aby to zrobić za pomocą tokena *. Dodałem atrybut required="false", aby zignorować schematy, które nie zawierają żadnego dopasowania.

<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: Zamieściłem tę odpowiedź bez przeczytaniu komentarzy w rachubę. Przepraszam za to.Używam maven plugin org.codehaus.mojo:jaxb2-maven-plugin:1.5 z wtyczką XJC org.jvnet.jaxb2_commons:jaxb2-basics-project:0.6.4 i wygląda na to, że działa tak ...

0

Kończę z podobnym problemem "zbyt wiele węzłów docelowych (3)", jednak nie mogę znaleźć żadnej odpowiedzi na żaden z strony ... Zamieszczanie rozwiązania, które znalazłem po wielu śladach i błędach ... Podstawowym pomysłem na rozwiązanie "zbyt wielu węzłów docelowych (3)" jest zapewnienie kompletnego XPATH węzła, który jest wielokrotny w twoim XSD.

Poniżej jest moim 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> 

i poniżej jest wiążąca plik JAXB który pracuje dla powyższej 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> 
Powiązane problemy