2

私はArborJSを試し、ナレッジツリーを構築しようとしています。これが私のテストエリアです(左クリックしてノードに入り、右クリックして最初に戻ります)。私は「人文科学」セクションの「すべて」を肉付けしているので、その領域で遊ぶことをお勧めします。

このツリーは、ウィキペディアの学問分野のリストの記事から作成しています。

今、私は1つのmySQLテーブルから(PHP経由で)データをプルしています。テーブル構造はTreeNodeID、ParentID、Titleです。「TreeNodeID」は主キー(自動インクリメント)、「ParentID」はノードの親、「Title」はノードに表示されるテキストです。

私は今、この記事の27ページ中7ページにいます。この手動入力プロセスを自動化するコンピューターの機能を利用していないように感じます。

すべての主題のテキストファイルを作成しました。次の形式です。

Anthropology
    Biological Anthropology
        Forensic Anthropology
        Gene-Culture Coevolution
        Human Behavioral Ecology
    Anthropological Linguistics
        Synchronic Linguistics
        Diachronic Linguistics
        Ethnolinguistics
        Socioloinguistics
    Cultural Anthropology
        Anthropology of Religion
        Economic Anthropology
Archaelogy
...

PHPを使用してこれを調べ、データベースに(各ノードの正しいParentIDを)入力するにはどうすればよいですか?

更新#3:作業コード(以下の正解で示されています)

<?php
//echo "Checkpoint 1";

$data = "
Social sciences
    Anthropology
        Biological anthropology
            Forensic anthropology
            Gene-culture coevolution
            Human behavioral ecology
            Human evolution
            Medical anthropology
            Paleoanthropology
            Population genetics
            Primatology
        Anthropological linguistics
            Synchronic linguistics (or Descriptive linguistics)
            Diachronic linguistics (or Historical linguistics)
            Ethnolinguistics
            Sociolinguistics
        Cultural anthropology
            Anthropology of religion
            Economic anthropology
            Ethnography
            Ethnohistory
            Ethnology
            Ethnomusicology
            Folklore
            Mythology
            Political anthropology
            Psychological anthropology
    Archaeology
        ...(goes on for a long time)
";

//echo "Checkpoint 2\n";

$lines = preg_split("/\n/", $data);

$parentids = array(0 => null);
$db = new PDO("host", 'username', 'pass');
$sql = 'INSERT INTO `TreeNode` SET ParentID = ?, Title = ?';
$stmt = $db->prepare($sql);

//echo "Checkpoint 3\n";

foreach ($lines as $line) {
    if (!preg_match('/^([\s]*)(.*)$/', $line, $m)) {
        continue;
    }
    $spaces = strlen($m[1]);
    //$level = intval($spaces / 4); //assumes four spaces per indent
    $level = strlen($m[1]); // if data is tab indented
    $title = $m[2];
    $parentid = ($level > 0 ? $parentids[$level - 1] : 1); //All "roots" are children of "Academia" which has an ID of "1";

    $rv = $stmt->execute(array($parentid, $title));

    $parentids[$level] = $db->lastInsertId();
    echo "inserted $parentid - " . $parentid . " title: " . $title . "\n";
}
?>
4

3 に答える 3

1

テストされていませんが、これでうまくいくはずです(PDOを使用):

<?php

$data = "
Anthropology
    Biological Anthropology
        Forensic Anthropology
        Gene-Culture Coevolution
        Human Behavioral Ecology
    Anthropological Linguistics
        Synchronic Linguistics
        Diachronic Linguistics
        Ethnolinguistics
        Socioloinguistics
    Cultural Anthropology
        Anthropology of Religion
        Economic Anthropology
Archaelogy
";

$lines = preg_split("/\n/", $data);

$parentids = array(0 => null);

$sql = 'INSERT INTO `table` SET ParentID = ?, Title = ?';
$stmt = $db->prepare($sql);

foreach ($lines as $line) {
    if (!preg_match('/^([\s]*)(.*)$/', $line, $m)) {
        continue;
    }
    #$spaces = strlen($m[1]);
    #$level = intval($spaces / 4); # if data is space indented
    $level = strlen($m[1]); # assumes data is tab indented
    $title = $m[2];

    $parentid = $level > 0
        ? $parentids[$level - 1]
        null;

    $rv = $stmt->execute(array($parentid, $title));

    $parentids[$level] = $db->lastInsertId();
}
于 2012-09-16T18:57:08.880 に答える
0

上記のようにインデントして、最初にテキストファイルにコピーアンドペーストする方が簡単だと思います。次に、それを解析します。

  • 各行を(一度に1つずつ)読み取り、ノードテキストを提供します。
  • 各インデントは新しい子であるため、前のノードは親IDです
  • 凹みをチェックします-\t一貫性がある場合はカウントします。またはカウントを維持しますindent level。0インデント(ルート)に注意してください。

これにより、各分野を含む連想配列を構築できます。次に、それを解釈します。例えば:

  • すべてのルートノード(ルートの最初の子)を取得し、増分IDを指定しますparse_id
  • 上から配列に沿って続行し、parse_idすべてのノードにsを割り当てます。
  • 次に、そのデータをMySQLに入れ始めます。あなたがするように、例えば、とmysqli_insert_id一緒に配列を追加します。これは、データベースで必要なものを親のに関連付けるために使用する必要があります。parse_iddb_idparent_idparse_id

一般的なスタディや一意のノードテキストをチェックしようとしていないと仮定すると、それは十分に簡単なはずです。

于 2012-09-16T18:49:48.053 に答える
0

あなたは以下で試すことができます

// parser.php

<?php
include_once './vendor/autoload.php';

use Symfony\Component\DomCrawler\Crawler;

$crawler = new Crawler(file_get_contents('http://en.wikipedia.org/wiki/List_of_academic_disciplines'));

$texts = $crawler->filter('.tocnumber + .toctext');
$numbers = $crawler->filter('.tocnumber');


$last = '';

for ($i=0; $i < count($numbers); $i++) {
    $value = $numbers->eq($i)->text();
    if(!preg_match('/\d+.\d+/', $value)) {
        // is a root discipline
        $last = $texts->eq($i)->text();
    } else {
        // is a leaf discipline
        $disciplines[$last][$texts->eq($i)->text()] = $texts->eq($i)->text();
    }
}

var_dump($disciplines);

これを使用すると、データベースなどで永続化するようなことができ、他のDOM解析タスクに役立ちます

SymfonyComponentsのCssSelectorとDomCrawlerを使用しました。インストールは簡単です。

composer.json

{
    "name": "wiki-parser",
    "require": {
        "php": ">=5.3.3",
        "symfony/dom-crawler": "2.1.0",
        "symfony/css-selector": "2.1.0"
    }
}

コンソールで

$ php composer.phar install

getcomposerを探してください

于 2012-09-16T19:57:14.893 に答える