2013-07-07 33 views
0

我正在使用BeSimpleSoapBundle在Symfony 2中生成webservice。 retrieveOrders方法的響應應該在工作流引擎中使用。使用Xpath查詢引用的XML元素

web服務的生成的響應是:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="..." xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<SOAP-ENV:Body> 
<ns1:retrieveOrdersResponse> 
    <return> 
    <item> 
     <id>1</id> 
     <lieferdatum>2013-07-03T10:53:38+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen /> 
    </item> 
    <item id="ref1"> 
     <id>10</id> 
     <lieferdatum>2013-07-03T10:53:38+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen> 
     <item> 
      <id>6</id> 
      <liefermenge>3</liefermenge> 
      <bestellung href="#ref1" /> 
      <produkt id="ref3"> 
      <id>1</id> 
      <bezeichnung>test</bezeichnung> 
      </produkt> 
      <abweichungen /> 
     </item> 
     </bestellpositionen> 
    </item> 
    <item id="ref2"> 
     <id>11</id> 
     <lieferdatum>2013-07-03T10:53:38+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen> 
     <item> 
      <id>7</id> 
      <liefermenge>3</liefermenge> 
      <bestellung href="#ref2" /> 
      <produkt href="#ref3" /> 
      <abweichungen /> 
     </item> 
     </bestellpositionen> 
    </item> 
    <item id="ref4"> 
     <id>12</id> 
     <lieferdatum>2013-07-03T10:53:38+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen> 
     <item> 
      <id>8</id> 
      <liefermenge>3</liefermenge> 
      <bestellung href="#ref4" /> 
      <produkt href="#ref3" /> 
      <abweichungen /> 
     </item> 
     </bestellpositionen> 
    </item> 
    <item id="ref5"> 
     <id>13</id> 
     <lieferdatum>2013-07-03T10:53:38+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen> 
     <item> 
      <id>9</id> 
      <liefermenge>3</liefermenge> 
      <bestellung href="#ref5" /> 
      <produkt href="#ref3" /> 
      <abweichungen /> 
     </item> 
     </bestellpositionen> 
    </item> 
    <item id="ref6"> 
     <id>14</id> 
     <lieferdatum>2013-07-03T10:53:38+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen> 
     <item> 
      <id>10</id> 
      <liefermenge>3</liefermenge> 
      <bestellung href="#ref6" /> 
      <produkt href="#ref3" /> 
      <abweichungen /> 
     </item> 
     </bestellpositionen> 
    </item> 
    <item> 
     <id>15</id> 
     <lieferdatum>2013-12-07T07:00:00+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen /> 
    </item> 
    <item> 
     <id>16</id> 
     <lieferdatum>2013-12-07T07:00:00+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen /> 
    </item> 
    <item id="ref7"> 
     <id>17</id> 
     <lieferdatum>2013-12-07T07:00:00+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen> 
     <item> 
      <id>11</id> 
      <liefermenge>2</liefermenge> 
      <bestellung href="#ref7" /> 
      <produkt href="#ref3" /> 
      <abweichungen /> 
     </item> 
     </bestellpositionen> 
    </item> 
    <item id="ref8"> 
     <id>18</id> 
     <lieferdatum>2013-12-17T07:00:00+00:00</lieferdatum> 
     <tatsaechlichesLieferdatum xsi:nil="true" /> 
     <bestellpositionen> 
     <item> 
      <id>12</id> 
      <liefermenge>2</liefermenge> 
      <bestellung href="#ref8" /> 
      <produkt href="#ref3" /> 
      <abweichungen /> 
     </item> 
     </bestellpositionen> 
    </item> 
    </return> 
</ns1:retrieveOrdersResponse> 

正如你所看到的,BeSimpleSoapBundle已經產生之前已經輸出鏈接XML元素。

而不是再次定義產品#ref3,它被<produkt href="#ref3" />引用。

但我怎麼可以通過Xpath訪問引用元素的屬性/節點? 具體:我如何獲得第一個產品名稱('bezeichnung')?

下面的XPath查詢是不工作:

/SOAP-ENV:Envelope/SOAP-ENV:Body/ns1:retrieveOrdersResponse/return/item[id=18]/bestellpositionen/item[id=12]/produkt/bezeichnung 

我的問題是:

  • 爲什麼它不工作?
  • 這些參考文獻是否標準化?
  • 如果它不適用於Xpath,是否有一種簡單的方法可以用XSLT解析結構?
  • 有沒有一種方法可以防止BeSimpleSoapBundle中的這種默認行爲?

預先感謝您!

更新

我的一個朋友告訴我,有一個if-then-else結構,它允許我 解決這樣的結構:

(if(orders/item[id=18]/bestellpositionen/item[id=12]/produkt/@href) 
then(orders/item/bestellpositionen/item/produkt[@id= fn:substring(/orders/item[id=18] /bestellpositionen/item[id=12]/produkt/@href, 2) ]) 
else (orders/item[id=18]/bestellpositionen/item[id=12]/produkt))/bezeichnung 

它的工作原理,儘管這並不完美。如果有一個簡化邏輯的專用功能,請告訴我!

+0

嘗試這種'// bezeichnung' – Ievgen

+0

不幸的是同樣的效果 – twiechert

回答

1

這樣一個XPath應該工作:

orders/item[id = 18]/bestellpositionen/item[id = 12]/produkt/bezeichnung | 
orders/item/bestellpositionen/item/produkt[id = 
    substring-after(../../../../item[id = 18]/bestellpositionen/item[id = 12] 
           /produkt/@href, '#')] 

,你可以做的另一件事就是用這種簡單的XSLT來解決所有的引用:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" /> 

    <xsl:key name="kRefTarget" match="*[@id]" use="@id"/> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- The [not(substring-after(@href, '#') = ancestor::*/@id)] portion prevents 
     infinite recursion on <bestellung> and anything else that references its 
     own ancestor. --> 
    <xsl:template match="*[@href] 
         [not(substring-after(@href, '#') = ancestor::*/@id)]"> 
    <xsl:apply-templates select="key('kRefTarget', substring-after(@href, '#'))" /> 
    </xsl:template> 
</xsl:stylesheet> 

你的樣品輸入運行之後,項目18的XML如下所示:

<item id="ref8"> 
    <id>18</id> 
    <lieferdatum>2013-12-17T07:00:00+00:00</lieferdatum> 
    <tatsaechlichesLieferdatum xsi:nil="true" /> 
    <bestellpositionen> 
    <item> 
     <id>12</id> 
     <liefermenge>2</liefermenge> 
     <bestellung href="#ref8" /> 
     <produkt id="ref3"> 
     <id>1</id> 
     <bezeichnung>test</bezeichnung> 
     </produkt> 
     <abweichungen /> 
    </item> 
    </bestellpositionen> 
</item> 
+0

非常感謝!這工作正常。在進行大量查詢時,這種轉換很重要。 – twiechert

+0

@twiechert很高興聽到這個消息。如果這解決了您的問題,我很感謝您通過單擊複選標記圖標將其標記爲正確答案。 :) – JLRishe