2012-05-24 24 views
0

我正在寫一個類,用類似mysql的語法讀取xml的內容(當然,它不完全是相同的語法,我忽略了很多東西,只是想要一些基本知識) 。在PHP中將類似sql的語法翻譯成xpath

首先,聲明是這樣的:

"SELECT name passwd FROM table WHERE id = 1 and description = 'desc'" 

一些基本規則:

  • 必須有一切之間的空白
  • 不經過兩年多的比較「去哪兒」

我沒有做任何事情,只是選擇語句的方法。 我將這條語句分解,將它排序成一個數組,然後嘗試將它翻譯成DOMXpath

它在沒有WHERE的情況下起作用。但我與其中子句(這裏是我迄今所做的:)

聲明掙扎:「選擇的名字用PW用戶WHERE ID =‘1’和說明=‘測試或測試2’」

數組的樣子:

array(4) { 
    ["type"]=> 
    string(6) "SELECT" 
    ["searchFields"]=> 
    array(2) { 
    ["searchField0"]=> 
    string(4) "name" 
    ["searchField1"]=> 
    string(2) "pw" 
    } 
    ["tableName"]=> 
    string(4) "user" 
    ["comparer"]=> 
    array(2) { 
    ["where0"]=> 
    array(3) { 
     ["field"]=> 
     string(2) "id" 
     ["operator"]=> 
     string(1) "=" 
     ["value"]=> 
     string(3) "'1'" 
    } 
    ["where1"]=> 
    array(4) { 
     ["splitTag"]=> 
     string(3) "and" 
     ["field"]=> 
     string(11) "description" 
     ["operator"]=> 
     string(1) "=" 
     ["value"]=> 
     string(15) "'test or test2'" 
    } 
    } 
} 

如何我想聲明轉化爲Xpath的用下面的代碼:

for ($i = 0; $i < count($arrQuery['searchFields']); $i++) { 
    $conditions = ""; 
    foreach ($arrQuery['comparer'] as $value) { 
     switch (count($arrQuery['comparer'])) { 
      case 1: 
       $conditions .= '//parent::content[@name="'.$value['field'].'" and text()='.$value['value'].']'; 
       break; 
      case 2: 
       if (!isset($value['splitTag']) || $value['splitTag'] == "and") { 
        $conditions .= '//parent::content[@name="'.$value['field'].'" and text()='.$value['value'].']'; 
        break; 
       } else { 
        //$conditions .= 'content[@'.$value['field'].' and text()='.$value['value'].']//parent::*'; 
       } 
       break; 
     } 
    } 
    $xpathquery = '//datarange[@name="'.$arrQuery['tableName'].'"]'.$conditions.'//content[@name="'.$arrQuery['searchFields']['searchField'.$i].'"]'; 
    $nodeList = $this->xpath->query($xpathquery); 
    foreach ($nodeList as $node) { 
     $arrContent['searchField'.$i][] = $node->nodeValue; 
    } 
} 

我的第一點是:如果IF子句中的條件案例2是con確定創建的xpath不工作(可能是父母或我的邏輯問題)

我的第二點是:我仍然不知道如何處理條件不匹配的情況,$ value [' splitTag']是「或」。如果任何人有一個提示如何解決,我會非常感謝。

/EDIT:好的,謝謝你的提示,這裏是我的XML的例子:

<database> 
    <datarange id="user"> 
    <dataset id="0"> 
     <content name="id"> 
     1 
     </content> 
     <content name="description"> 
     test or test2 
     </content> 
     <content name="name"> 
     Name 
     </content> 
     <content name="pw"> 
     Passwort 
     </content> 
    </dataset> 
    <dataset id="1"> 
     <content name="name"> 
     Name2 
     </content> 
     <content name="pw"> 
     Passwort2 
     </content> 
    </dataset> 
    </datarange> 
    <datarange id="config"> 
    <dataset id="0"> 
     <content name="type"> 
     command 
     </content> 
     <content name="name"> 
     lab 
     </content> 
     <content name="type"> 
     request 
     </content> 
     <content name="target"> 
     target_name 
     </content> 
     <content name="desc"> 
     Address Book 
     </content> 
    </dataset> 
    </datarange> 
</database> 
+0

您將需要發佈一個源XML查詢語言示例正在處理 –

+0

編輯:xml添加。 – Mohammer

回答

1

鑑於你的輸入文檔和查詢:SELECT name pw FROM user WHERE id = '1' and description = 'test or test2你將不得不建立自己下面的XPath獲得到具有價值的dataset節點需要:

//datarange[@id = 'user']/dataset 
     [normalize-space(content[@name = 'id']) = '1'] 
     [normalize-space(content[@name = 'description']) = 'test or test2'] 

這一次會給你dataset節點,然後可以運行下面的:

normalize-space(content[@name = 'name']) 

得到name和:

normalize-space(content[@name = 'pw']) 

這裏有一個簡單的XSLT來測試它:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="//datarange[@id = 'user']/dataset 
       [normalize-space(content[@name = 'id']) = '1'] 
       [normalize-space(content[@name = 'description']) = 'test or test2']"/> 
    </xsl:template> 

    <xsl:template match="dataset"> 
     name: <xsl:value-of select="normalize-space(content[@name = 'name'])"/> 
     pwd: <xsl:value-of select="normalize-space(content[@name = 'pw'])"/> 
    </xsl:template> 

</xsl:stylesheet> 

當適用於您的輸入文檔就會產生:

name: Name 
pwd: Passwort 

您現在可以將它分解到您的查詢SQL-像XPath引擎一樣。

但還有一件事。如果您可以升級到XPath 2.0,則可以嘗試使用conditionalquantified表達式使XPath更類似於查詢。誰知道,也許你不會需要類似SQL的語法。另外還有XQuery

+0

非常感謝!那就做到了! – Mohammer