php - 循环包含一些子项和子项的 XML 以在 PHP 中以表格形式输出
问题描述
<?xml version="1.0" encoding="utf-8"?>
<Agenda>
<responseMessage>Success.</responseMessage>
<jobs>
<trip>
<header>
<reservation_number>10562</reservation_number>
<recipient_first>John</recipient_first>
<recipient_middle>H</recipient_middle>
<recipient_last>Doe</recipient_last>
</header>
<legs>
<leg>
<trip_id>42390</trip_id>
<leg_status>Active</leg_status>
<pickup_date>12/24/2020</pickup_date>
<pickup_time>0600</pickup_time>
<pickup_state>New York</pickup_state>
<pickup_country>USA</pickup_country>
<dropoff_state>Pennsylvania</dropoff_state>
<dropoff_country>USA</dropoff_country>
</leg>
<leg>
<trip_id>42391</trip_id>
<leg_status>Canceled</leg_status>
<pickup_date>01/02/2021</pickup_date>
<pickup_time>1800</pickup_time>
<pickup_state>Pennsylvania</pickup_state>
<pickup_country>USA</pickup_country>
<dropoff_state>New York</dropoff_state>
<dropoff_country>USA</dropoff_country>
</leg>
</legs>
<secondary_services>
<service>
<service_leg_id>42390</service_leg_id>
<service_name>Tolls</service_name>
<service_rate>3.00</service_rate>
<service_quantity>1</service_quantity>
</service>
<service>
<service_leg_id>42390</service_leg_id>
<service_name>addtl.miles</service_name>
<service_rate>3.40</service_rate>
<service_quantity>25</service_quantity>
</service>
<service>
<service_leg_id>42391</service_leg_id>
<service_name>Tolls</service_name>
<service_rate>18.00</service_rate>
<service_quantity>1</service_quantity>
</service>
<service>
<service_leg_id>42391</service_leg_id>
<service_name>addtl.miles</service_name>
<service_rate>3.40</service_rate>
<service_quantity>29</service_quantity>
</service>
</secondary_services>
</trip>
<trip>
<header>
<reservation_number>10575</reservation_number>
<recipient_first>Emily</recipient_first>
<recipient_middle></recipient_middle>
<recipient_last>Santana</recipient_last>
</header>
<legs>
<leg>
<trip_id>64593</trip_id>
<leg_status>Active</leg_status>
<pickup_date>12/27/2020</pickup_date>
<pickup_time>1700</pickup_time>
<pickup_state>New York</pickup_state>
<pickup_country>USA</pickup_country>
<dropoff_state>Connecticut</dropoff_state>
<dropoff_country>USA</dropoff_country>
</leg>
<leg>
<trip_id>64594</trip_id>
<leg_status>Active</leg_status>
<pickup_date>01/04/2021</pickup_date>
<pickup_time>1200</pickup_time>
<pickup_state>Connecticut</pickup_state>
<pickup_country>USA</pickup_country>
<dropoff_state>New York</dropoff_state>
<dropoff_country>USA</dropoff_country>
</leg>
</legs>
<secondary_services>
<service>
<service_leg_id>64593</service_leg_id>
<service_name>Tolls</service_name>
<service_rate>0.00</service_rate>
<service_quantity>0</service_quantity>
</service>
<service>
<service_leg_id>64593</service_leg_id>
<service_name>addtl.miles</service_name>
<service_rate>3.40</service_rate>
<service_quantity>10</service_quantity>
</service>
<service>
<service_leg_id>64594</service_leg_id>
<service_name>Tolls</service_name>
<service_rate>04.00</service_rate>
<service_quantity>1</service_quantity>
</service>
<service>
<service_leg_id>64594</service_leg_id>
<service_name>addtl.miles</service_name>
<service_rate>3.40</service_rate>
<service_quantity>11</service_quantity>
</service>
</secondary_services>
</trip>
</jobs>
</Agenda>
我无法通过 foreach 循环循环输出这样的表。
预订编号 | 地位 | 姓名 | 日期 | 时间 | PU位置 | 做位置 | 过路费 | 添加。英里 |
---|---|---|---|---|---|---|---|---|
10562-42390 | 积极的 | 约翰·H·多伊 | 2020 年 12 月 24 日 | 0600 | 美国纽约 | 美国宾夕法尼亚州 | 3.00 | 25 |
10562-42391 | 取消 | 约翰·H·多伊 | 2021 年 1 月 2 日 | 1800 | 美国宾夕法尼亚州 | 美国纽约 | 18.00 | 29 |
10575-64593 | 积极的 | 艾米莉桑塔纳 | 2020 年 12 月 27 日 | 1700 | 美国纽约 | 美国康涅狄格州 | 0.00 | 10 |
10575-64594 | 积极的 | 艾米莉桑塔纳 | 2021 年 1 月 4 日 | 1200 | 美国康涅狄格州 | 美国纽约 | 4.00 | 11 |
我在另一个 foreach 循环中尝试了一个带有键和值的 foreach 循环,但是我无法将 service 元素与 leg 元素匹配,因为它们具有独立的循环。
解决方案
考虑一下XSLT,这是一种专用语言,旨在转换 XML 文件,例如处理所有值的连接和腿 ID 的匹配。如果需要,XSLT 甚至可以转换为 HTML。PHP 可以使用库运行带有其xsl类的 XSLT 1.0 脚本。DOMDocument
XSLT (另存为 .xsl 文件,特殊的 .xml 文件)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="leg_key" match="leg" use="trip_id" />
<xsl:template match="/Agenda">
<xsl:copy>
<xsl:apply-templates select="descendant::leg[generate-id() =
generate-id(key('leg_key', trip_id)[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="leg">
<xsl:copy>
<xsl:variable name="curr_leg_id" select="trip_id"/>
<Reservation_id>
<xsl:value-of select="concat(ancestor::trip/header/reservation_number, '-', trip_id)"/>
</Reservation_id>
<Status><xsl:value-of select="leg_status"/></Status>
<Name><xsl:value-of select="concat(ancestor::trip/header/recipient_first, ' ',
ancestor::trip/header/recipient_middle, ' ',
ancestor::trip/header/recipient_last)"/></Name>
<Date><xsl:value-of select="pickup_date"/></Date>
<Time><xsl:value-of select="pickup_time"/></Time>
<PU_location><xsl:value-of select="concat(pickup_state, ' ', pickup_country)"/></PU_location>
<DO_location><xsl:value-of select="concat(dropoff_state, ' ', dropoff_country)"/></DO_location>
<Tolls>
<xsl:value-of select="ancestor::trip/secondary_services/service[service_leg_id = $curr_leg_id and
service_name='Tolls']/service_rate"/>
</Tolls>
<Addl>
<xsl:value-of select="ancestor::trip/secondary_services/service[service_leg_id = $curr_leg_id and
service_name='addtl.miles']/service_quantity"/>
</Addl>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
PHP ($new_xml
用于最终使用需求)
// LOAD XML
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load('/path/to/Input.xml');
// LOAD XSLT
$xsl = new DOMDocument('1.0', 'UTF-8');
$xsl->load('/path/to/XSLT_Script.xsl');
// INITIALIZE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// TRANSFORM ORIGINAL DOCUMENT
$new_xml = $proc->transformToDoc($xml);
// ECHO TO SCREEN
echo $new_xml->saveXML();
// SAVE TO FILE
file_put_contents('/path/to/Output.xml', $new_xml);
推荐阅读
- android - 错误:“智能转换为字符串是不可能的,因为“消息”是一个可变属性”
- c++ - 设置大小时,std::vector 的性能会降低吗?
- neo4j - 提高 Neo4j 查询性能
- php - PHP simplexml_load_file() function skip the XML tag which has ":"
- highcharts - Cursor offset after scaling Highstock chart
- amazon-web-services - 授予 S3 存储桶访问权限的跨账户角色 - 权限被拒绝
- python - 为什么我的连接对象突然成为主要的光标对象?
- webpack - 通过 Webpack 创建带有哈希的供应商包并在同构应用程序中使用它
- elasticsearch - ElasticSearch URI 搜索空字段
- asp.net-mvc - MVC 操作方法中的 NULL 会话