基于XML文件(PHP, Jquery)的页面生成

Page generation based on XML files (PHP, Jquery)

本文关键字:Jquery 文件 XML PHP 基于      更新时间:2023-09-26

所以我有需要在PHP页面中作为搜索结果使用的XML数据。
问题- XML的结构很糟糕(一个"索引"文件带有指向其他XML文件的链接),而且整个文件的大小非常大(从1000到20+K XML文件,总共10甚至更多mb)。
我研究了很多不同的工具:XMLreader、XML Parser和一点JQuery。但我不确定哪一个更适合这个任务。
什么,我认为最好的解决办法是facebook风格的"按加载更多"的页面加载自己,加载"索引"XML(可能在一个隐藏的输入字段或div,以便它可以被JQuery读取),然后开始主动读取XML文件,在索引中列出,并在页面上动态生成结果。我确实需要把所有的数据存储在某种内存中,因为我还需要对其进行分析。
问:哪一种方法更好,我能从中受益吗?还是我完全看错了方向?

我尝试使用XMLreader和解析器以及SimpleXMLElement + for=loop进行严格的PHP读取,但是一旦我将第二次读取(从"索引")放入方程式中,页面就会因为加载时间太长而中断,这是30MB/s的互联网。我没有太多的JQuery经验,所以这就是我寻求建议的原因。


附注:我从http://www.clinicaltrials.gov
获取XML一个 "Index"的例子:http://www.clinicaltrials.gov/search?term=attack&count=1856&displayxml=true
如果你加上"?"

displayxml=true"对于每个"url"它将是一个我需要读取的XML文件

我要做的是:

由于站点提供了一些有用的查询字符串,如&count=,因此可以利用这个优势。

这意味着你真的不需要处理和查询成千上万的行。

通常,你只需要像这样查询外部网站:

http://www.clinicaltrials.gov/search?term=heart%20attack&count=10&displayxml=true&pg=1

所以限制每个请求。例如:每次使用10

然后开始构建服务器端。

客户端网站由您决定,这只是个人喜好,但我将在这个例子中使用DataTables

下面的代码只是在上面的示例url中重新创建相同的结构:

$search_term = 'attack';
$count = 10;
$query = http_build_query(array(
    'term' => $search_term,
    'count' => $count,
    'displayxml' => 'true',
    'pg' => $draw,
));
$main_url = 'http://www.clinicaltrials.gov/search?' . $query;

构建正确的URL后,只需请求所需的XML。最后,在收集了所需的所有数据(分块数据)之后。在客户端呈现它。

完整示例:Also Sample Fiddle

index.php

if($_SERVER['REQUEST_METHOD'] == 'POST') {
    $draw = isset($_POST['draw']) ? $_POST['draw'] : 1;
    $search_term = 'attack';
    $count = 10;
    $query = http_build_query(array(
        'term' => $search_term,
        'count' => $count,
        'displayxml' => 'true',
        'pg' => $draw,
    ));
    $main_url = 'http://www.clinicaltrials.gov/search?' . $query;
    $contents = file_get_contents($main_url);
    $xml = simplexml_load_string($contents);
    $total_results = (string) $xml->attributes()['count'];
    $data = array();
    $data['draw'] = $draw;
    $data['recordsTotal'] = $total_results;
    $data['recordsFiltered'] = $total_results;
    foreach($xml->clinical_study as $entry) {
        $data['data'][] = json_decode(json_encode($entry), true);
    }
    echo json_encode($data);
    exit;
}
?>
<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.css" />
<table border="1" class="display dataTable" cellspacing="0" width="100%">
    <thead>
        <tr>
            <th>Order</th>
            <th>Score</th>
            <th>Nct ID</th>
            <th>URL</th>
            <th>Title</th>
            <th>Status</th>
            <th>Condition Summary</th>
            <th>Last Changed</th>
        </tr>
    </thead>
    <tfoot>
        <tr>
            <th>Order</th>
            <th>Score</th>
            <th>Nct ID</th>
            <th>URL</th>
            <th>Title</th>
            <th>Status</th>
            <th>Condition Summary</th>
            <th>Last Changed</th>
        </tr>
    </tfoot>
</table>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    $('.display').dataTable({
        'processing': true,
        'serverSide': true,
        'ajax': {
            'url': document.URL,
            'type': 'POST',
        },
        "columns": [
            { "data": "order" },
            { "data": "score" },
            { "data": "nct_id" },
            { "data": "url" },
            { "data": "title" },
            { "data": "status" },
            { "data": "condition_summary" },
            { "data": "last_changed" },
        ],
        bFilter: false, bInfo: false, bSort: false,
    });
});
</script>

这里的基本思想是你不需要立即请求那1000行。

您可以使用XSL获取clinicaltrials.gov XML并将其转换为相同的XML格式,包括HTML。XSL是一种用于转换XML的语言。

PHP甚至有内置的XSL处理器:http://php.net/manual/en/book.xsl.php

附带说明一下,我使用XSL将DocBook XML文件(一种语义标记语言)转换为Twitter Bootstrap HTML。

例如,使用您提供的示例(http://www.clinicaltrials.gov/search?term=attack&count=1856&displayxml=true),如果您希望将所有临床研究的标题显示为一个列表,那么以下XSL样式表可以完成这项工作:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
  <xsl:template match="/">
    <ul>
      <xsl:apply-templates/>
    </ul>
  </xsl:template>
  <xsl:template match="search_results">
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="clinical_study">
    <li><xsl:value-of select="title"/></li>
  </xsl:template>
</xsl:stylesheet>

XSL样式表在文档的根位置输入源XML文档。然后遍历树。只要它找到一个与定义模板匹配的元素,它就执行该模板。非常酷的东西!要使自己适应XSL编程范式需要一段时间,但是一旦掌握了它的窍门,它就会非常强大。

请注意,我只是把它作为我头脑中的一个玩具例子来写的。我不确定这是否能正确执行。

编辑1:

(OP询问执行分析,例如计算特定类型的所有元素)

查看示例XML结果,似乎确定试验是否处于阶段3的唯一方法是检查<title>元素的文本。这仍然很容易在XSL的能力范围之内(在XPath的一些帮助下)。

<xsl:variable name="countPhase3">
   <xsl:value-of select="count(//title[text() = 'Phase 3' | text() = 'Phase III']"/>
</xsl:variable>

我要再次警告你,这只是我头脑中的一个例子。