循环 XML 包含几个 child 和 children 输出为 table in PHP
Looping XML containing a few child and children to output as a table in 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 循环以输出 table,例如这个。
Reservation ID
Status
Name
Date
Time
PU Location
DO Location
Tolls
Addlt. Miles
10562-42390
Active
John H Doe
12/24/2020
0600
New York, USA
Pennsylvania, USA
3.00
25
10562-42391
Canceled
John H Doe
01/02/2021
1800
Pennsylvania, USA
New York, USA
18.00
29
10575-64593
Active
Emily Santana
12/27/2020
1700
New York, USA
Connecticut, USA
0.00
10
10575-64594
Active
Emily Santana
01/04/2021
1200
Connecticut, USA
New York, USA
4.00
11
我尝试了一个 foreach 循环,其中的键和值位于另一个 foreach 循环中,但我无法将 service 元素与 leg 元素相匹配,因为它们具有独立的循环。
考虑 XSLT, the special-purpose language designed to transform XML files such as handling all the concatenation of values and matching of leg ids. If needed, XSLT can even convert to HTML. PHP can run XSLT 1.0 scripts with its xsl class 使用 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);
<?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 循环以输出 table,例如这个。
Reservation ID | Status | Name | Date | Time | PU Location | DO Location | Tolls | Addlt. Miles |
---|---|---|---|---|---|---|---|---|
10562-42390 | Active | John H Doe | 12/24/2020 | 0600 | New York, USA | Pennsylvania, USA | 3.00 | 25 |
10562-42391 | Canceled | John H Doe | 01/02/2021 | 1800 | Pennsylvania, USA | New York, USA | 18.00 | 29 |
10575-64593 | Active | Emily Santana | 12/27/2020 | 1700 | New York, USA | Connecticut, USA | 0.00 | 10 |
10575-64594 | Active | Emily Santana | 01/04/2021 | 1200 | Connecticut, USA | New York, USA | 4.00 | 11 |
我尝试了一个 foreach 循环,其中的键和值位于另一个 foreach 循环中,但我无法将 service 元素与 leg 元素相匹配,因为它们具有独立的循环。
考虑 XSLT, the special-purpose language designed to transform XML files such as handling all the concatenation of values and matching of leg ids. If needed, XSLT can even convert to HTML. PHP can run XSLT 1.0 scripts with its xsl class 使用 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);