首页 文章

选择具有XPath的节点以使用JAXB绑定类的子集

提问于
浏览
10

Simplified Question: 选择具有以字符串"Notification"结尾的属性的所有XML节点的XPath是什么 . 此代码段中的第一个和第三个节点:

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

Detailed Question:

我想从xsd模式中选择多个complexTypes来与JAXB绑定 . 这适用于单个类: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>

以下是架构架构文件中的相关代码段:

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

我希望绑定适用于所有通知对象 . 他们都以“通知”结束

我试过改变XPath

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

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

但它不起作用 .

另一种方法是尝试选择具有子项“order-summary”和“serial-number”的所有节点,因为我知道只有Notification对象具有这些 .

UPDATE: @Lee Greco的解决方案正确选择了我想要的节点,但不幸的是,继承插件与多个节点不兼容:

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

我最后只是单独枚举它们 .

3 回答

  • 5

    随着

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

    表达式,您要求所有元素名称以'Notification'结尾的元素 . 您真的想要求name属性以'Notification'结尾的所有元素 .

    试试这个:

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

    我有同样的问题 . 我发现有一个 multiple 属性被XJC用来允许多个节点匹配 .

    我还希望绑定应用于每个模式位置 . xs:anyURI 没有用,但我找到了使用 * 令牌的方法 . 我添加了 required="false" 属性以忽略不包含任何匹配的模式 .

    <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: 我在没有阅读问题评论的情况下发布了这个答案 . 对不起 . 我正在使用maven插件 org.codehaus.mojo:jaxb2-maven-plugin:1.5 和XJC插件 org.jvnet.jaxb2_commons:jaxb2-basics-project:0.6.4 ,它似乎像这样工作......

  • 5

    我最终得到一个类似的问题“太多的目标节点(3)”然而在任何网站上找不到任何答案...发布我经过大量的追踪和错误后发现的解决方案...解决的基本思路“太多目标节点(3)“是给出XSD中多个节点的完整XPATH .

    以下是我的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>
    

    以下是适用于上述XSD的JAXB绑定文件:

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

相关问题