在前端显示 xml 数据

Show xml data in Frontend

是否可以从缓存的 xml 文件中获取数据,然后在前端显示它们?

我正在考虑在 TYPO3 扩展中使用它的域模型(和 getter/setter)但没有数据库 table。然后用 SimpleXML 填充数据只是为了将它们“存储”在内存中。至少在前端显示来自领域模型的数据。但我不知道这种方法是否正确,或者有更好的方法吗?特别是设置持久层我不明白。

对于任何帮助,我非常感谢你提前付出的努力。

我找到了一个“可接受的”解决方案。我的做法是:

  1. 从 xml 文件中获取所有项目
  2. 添加一个 slug 字段
  3. 对项目进行排序
  4. 在前端显示已排序的项目
  5. 创造独一无二的漂亮url

1.从 xml 文件中获取所有项目

控制器:listAction、detailAction

public function listAction() {
    $jobs = $this->xmlDataRepository->findAll();
    $jobsArray = $this->simpleXmlObjToArr($jobs);
    $jobsArraySorted = $this->sortJobsByTitle($jobsArray);
    $this->view->assign('jobs', $jobsArraySorted);
}

public function detailAction($slugid) {
    $job = $this->xmlDataRepository->findBySlugWithId($slugid);
    $this->view->assign('job', $job[0]);
}

存储库:findAll、findBySlugWithId

public function findAll() {
    $objectStorage = new ObjectStorage();
    $dataFolder = ConfigurationService::setDataFolder();
    $xmlFile = glob($dataFolder . '*.xml')[0];
    $xmlData = simplexml_load_file($xmlFile,'SimpleXMLElement',LIBXML_NOWARNING);

    // error handling
    if ($xmlData === false) {
        ...
    }

    foreach($xmlData->children() as $job) {
        $objectStorage->attach($job);
    }
    return $objectStorage;
}

public function findBySlugWithId($slugid) {
    // get id from slugid
    $id = substr($slugid,strrpos($slugid,'-',-1)+1);
    $objectStorage = new ObjectStorage();
    $dataFolder = ConfigurationService::setDataFolder();
    $xmlFile = glob($dataFolder . '*.xml')[0];
    $xmlData = simplexml_load_file($xmlFile,'SimpleXMLElement',LIBXML_NOWARNING);

    // error handling
    if ($xmlData === false) {
        ...
    }

    $jobfound = false;

    foreach($xmlData->children() as $job) {
        if ($job->JobId == $id) {
            $objectStorage->attach($job);
            $jobfound = true;
        }
    }

    // throw 404-error
    if (!$jobfound) {
        $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
            $GLOBALS['TYPO3_REQUEST'],
            'Ihre angeforderte Seite wurde nicht gefunden',
            ['code' => PageAccessFailureReasons::PAGE_NOT_FOUND]
        );
        throw new ImmediateResponseException($response, 9000006460);
    }

    return $objectStorage;
}

2。添加一个 slug 字段(控制器)

protected function simpleXmlObjToArr($obj) {
    // 2-dimensional array
    $array = [];
    foreach($obj as $item){
        $row = [];
        foreach($item as $key => $val){
            $row[(string)$key] = (string)$val;
        }

        //add slug field, build it with Title
        $row['Slug'] = $this->convertToPathSegment($row['Titel']);

        // add $row to $array
        array_push($array,$row);
    }
    return $array;
}

3。对项目进行排序(控制器)

protected function sortJobsByTitle(array $jobs) {
    $title = array();
    $id = array();

    foreach ($jobs as $key => $job) {
        $title[$key] = $job['Titel'];
        $id[$key] = $job['JobId'];
    }

    // sort jobs array according to title, uid (uid because if there are courses with the same title!)
    array_multisort($title,SORT_ASC, $id,SORT_ASC, $jobs,SORT_STRING);

    return $jobs;
}

4。在前端显示排序的项目(模板)

List.html:

...
<ul>
    <f:for each="{jobs}" as="job">
        <li>
            <f:comment>
                <f:link.action class="" pageUid="2" action="show" arguments="{id: job.JobId, slug: job.Slug}">{job.Titel}</f:link.action> ({job.JobId})<br>
                <f:link.action class="" pageUid="2" action="detail" arguments="{xml: job}">NEW {job.Titel}</f:link.action> ({job.JobId})
            </f:comment>

            <f:variable name="slugid" value="{job.Slug}-{job.JobId}"/>
            <f:link.action class="" pageUid="2" action="detail" arguments="{slugid: slugid}"><f:format.raw>{job.Titel}</f:format.raw></f:link.action> ({job.JobId})
        </li>
    </f:for>
</ul>
...

Detail.html:

...
<f:image src="{job.Grafik}" width="500" alt="Detailstellenbild" />
<p><strong><f:format.raw>{job.Titel}</f:format.raw></strong> ({job.JobId})</p>
<p>Region: {job.Region}</p>
<f:format.html>{job.Beschreibung}</f:format.html>
...

5.打造独一无二的漂亮url

...
routeEnhancers:
  XmlJobDetail:
    type: Extbase
    limitToPages:
      - 2
    extension: Wtdisplayxmldata
    plugin: Displayxmldata
    routes:
      -
        routePath: '/{job-slugid}'
        _controller: 'XmlData::detail'
        _arguments:
          job-slugid: slugid
    defaultController: 'XmlData::list'
    aspects:
      job-slugid:
        type: XmlDetailMapper

Routing/Aspect/XmlDetailMapper.php:

use TYPO3\CMS\Core\Routing\Aspect\StaticMappableAspectInterface;
use TYPO3\CMS\Extbase\Utility\DebuggerUtility;

class XmlDetailMapper implements StaticMappableAspectInterface {

    /**
     * {@inheritdoc}
     */
    public function generate(string $value): ?string
    {
         return $value !== false ? (string)$value : null;
    }

    /**
     * {@inheritdoc}
     */
    public function resolve(string $value): ?string
    {
         return isset($value) ? (string)$value : null;
    }

}