在前端显示 xml 数据

发布于 2025-01-13 04:19:25 字数 221 浏览 0 评论 0原文

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

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

对于任何帮助,我非常感谢您提前所做的努力。

Is it possible fetching data from a cached xml file and then showing them on front end?

I was thinking doing it in a TYPO3 extension and with its domain model (and getter/setter) but without a database table. And then filling in data with SimpleXML just to "store" them in memory. At least display the data from domain model with fluid on front end. But I don't know is this approach right or is there a better way to do that? In particular setting up the persistence layer I don't understand.

For any help I thank you very much for your effort in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不如归去 2025-01-20 04:19:25

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

  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.创建独特的漂亮网址

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

}

I found an "acceptable" solution. My approach for that was:

  1. Get all items from xml file
  2. Add a slug field
  3. Sort the items
  4. Display sorted items on the front end
  5. Create unique pretty url

1. Get all items from xml file

Controller: 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]);
}

Repository: 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. Add a slug field (controller)

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. Sort the items (controller)

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. Display sorted items on the front end (templates)

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. Create unique pretty 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;
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文