0

私はmysqlのような構文でxmlのコンテンツを読み取るクラスを書いています(もちろん、完全に同じ構文ではなく、多くのことを無視していますが、いくつかの基本が必要です)。

まず、ステートメントは次のようになります。

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

いくつかの基本的なルール:

  • すべての間に空白が必要です
  • 「WHERE」の後の比較は 2 つまで

select文のメソッド以外は何もしていません。ステートメントを展開し、配列に並べ替えてから、DOMXpath に変換しようとします。

WHERE がない場合に機能します。しかし、私はwhere句に苦労しています(ここで私がこれまでに行ったこと:)

ステートメント: "SELECT name pw FROM user WHERE id = '1' and description = 'test or test2'"

配列は次のようになります。

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

私の最初のポイントは、ケース2のif節の条件が確認された場合、作成されたxpathが機能していないことです(親または私のロジックに問題がある可能性があります)

2 つ目のポイントは、条件が一致せず、$value['splitTag'] が "or" である場合の処理​​方法がまだわかりません。誰かがそれを解決する方法のヒントを持っていれば、私はとても感謝しています.

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

1 に答える 1

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-like-to-XPath エンジンに組み込むことができます。

もう1つ。XPath 2.0 にアップグレードできる場合は、XPath をよりクエリに似たものにするために、条件式と量化式を試してみてください。そして、そもそも SQL のような構文は必要ないかもしれません。さらに、XQueryがあります。

于 2012-05-26T17:05:40.297 に答える