在XML文件中组合两个元素

问题描述 投票:1回答:2

首先感谢您的帮助!

我有一个看起来像这样的xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE tv SYSTEM "xmltv.dtd">

<tv source-info-url="http://tvschedule.zap2it.com/" source-info-name="zap2it.com" generator-info-name="zap2xml" generator-info-url="[email protected]">
<channel id="I16689330.labs.zap2it.com">
    <display-name>502 WCBSDT</display-name>
    <display-name>502</display-name>
    <display-name>WCBSDT</display-name>
    <icon src="https://zap2it.tmsimg.com/h3/NowShowing/16689/s28711_h3_aa.png" />
</channel>
<programme start="20180303203000 -0500" stop="20180303230000 -0500" channel="I20453335.labs.zap2it.com">
    <title lang="en">NBA Basketball</title>
    <sub-title lang="en">Boston Celtics at Houston Rockets</sub-title>
    <desc lang="en">From the Toyota Center in Houston.</desc>
    <category lang="en">Sports</category>
    <category lang="en">Basketball</category>
    <length units="minutes">120</length>
    <icon src="https://zap2it.tmsimg.com/assets/p14464724_tb2_v5_aa.jpg" />
    <url>https://tvlistings.zap2it.com//overview.html?programSeriesId=SP00371600&amp;tmsId=SP003716000000</url>
    <episode-num system="dd_progid">SP00371600.0000</episode-num>
    <new />
    <subtitles type="teletext" />
</programme>
</tv>

我想生成这样的结合标题和子标题的东西:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE tv SYSTEM "xmltv.dtd">

<tv source-info-url="http://tvschedule.zap2it.com/" source-info-name="zap2it.com" generator-info-name="zap2xml" generator-info-url="[email protected]">
<channel id="I16689330.labs.zap2it.com">
    <display-name>502 WCBSDT</display-name>
    <display-name>502</display-name>
    <display-name>WCBSDT</display-name>
    <icon src="https://zap2it.tmsimg.com/h3/NowShowing/16689/s28711_h3_aa.png" />
</channel>
<programme start="20180303203000 -0500" stop="20180303230000 -0500" channel="I20453335.labs.zap2it.com">
    <title lang="en">NBA Basketball: Boston Celtics at Houston Rockets</title>
    <desc lang="en">From the Toyota Center in Houston.</desc>
    <category lang="en">Sports</category>
    <category lang="en">Basketball</category>
    <length units="minutes">120</length>
    <icon src="https://zap2it.tmsimg.com/assets/p14464724_tb2_v5_aa.jpg" />
    <url>https://tvlistings.zap2it.com//overview.html?programSeriesId=SP00371600&amp;tmsId=SP003716000000</url>
    <episode-num system="dd_progid">SP00371600.0000</episode-num>
    <new />
    <subtitles type="teletext" />
</programme>
</tv>

如果它可以用一个更好的PHP脚本完成

php xml
2个回答
1
投票

因此,如果我们在$string中有XML字符串,我们可以使用simplexml_load_string将其解析为XML对象:

$xml = simplexml_load_string($string);

然后访问元素作为对象属性:

> echo $xml->title;
NBA Basketball

要构建所需的组合属性,它就像直观一样(注意必须如何处理短划线特殊字符):

$xml->title .= ': '.$xml->{'sub-title'};

因为我们已将子标题属性合并到标题中,所以我们不再需要它:

unset($xml->{'sub-title'});

然后打印整个对象:

> echo $xml->asXML();
<?xml version="1.0"?>
<programme start="20180303203000 -0500" stop="20180303230000 -0500" channel="I20453335.labs.zap2it.com">
    <title lang="en">NBA Basketball: Boston Celtics at Houston Rockets</title>

    <desc lang="en">From the Toyota Center in Houston.</desc>
    <category lang="en">Sports</category>
    <category lang="en">Basketball</category>
    <length units="minutes">120</length>
    <icon src="https://zap2it.tmsimg.com/assets/p14464724_tb2_v5_aa.jpg"/>
    <url>https://tvlistings.zap2it.com//overview.html?programSeriesId=SP00371600&amp;tmsId=SP003716000000</url>
    <episode-num system="dd_progid">SP00371600.0000</episode-num>
    <new/>
    <subtitles type="teletext"/>
</programme>

样本完成执行:

<?php 
$string = file_get_contents('xmltv.xml'); 
$xml = simplexml_load_string($string); 
$xml->title .= ': '.$xml->{'sub-title'}; 
unset($xml->{'sub-title'}); 
file_put_contents('xmltv.xml', $xml->asXML());
?>

0
投票

或者,考虑XSLT,这是专门用于转换XML文件的专用语言。 PHP可以使用其php-xsl类运行XSLT 1.0(确保它在.ini文件中启用)。此外,XSLT是可移植的,不需要PHP来运行它。大多数其他语言(Java,Python,Perl,VB)可以运行这样的脚本甚至独立的XSLT processors

具体来说,在XSLT脚本下运行Identity Transform以按原样复制文档,然后使用标题和副标题的concat()重写程序节点,最后再现所有其他节点和属性。虽然这看起来有点过分,但如果您的XML要大得多并且维护了许多程序节点,那么这个XSLT将结合所有标题和子标题而不进行任何循环。

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="*"/>

    <!-- IDENTITY TRANSFORM -->
    <xsl:template match="node()|@*">  
        <xsl:copy> 
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <!-- REWRITE PROGRAMME -->
    <xsl:template match="programme"> 
        <xsl:copy>     
            <xsl:copy-of select="@*"/>
            <title><xsl:value-of select="concat(title, ' ', sub-title)" /></title>
            <xsl:apply-templates select="*[name()!='title' and name()!='sub-title']" /> 
        </xsl:copy>       
    </xsl:template>

</xsl:stylesheet>

PHP

$xml = new DOMDocument;
$xml->load('Input.xml');

$xsl = new DOMDocument;
$xsl->load('XSLT_Script.xsl');

// Configure transformer
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);

// Transform XML source
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);

// Output to console
echo $newXML;

// Output to file
file_put_contents('Output.xml', $newXML);

产量

<programme start="20180303203000 -0500" stop="20180303230000 -0500" channel="I20453335.labs.zap2it.com">
  <title>NBA Basketball Boston Celtics at Houston Rockets</title>
  <desc lang="en">From the Toyota Center in Houston.</desc>
  <category lang="en">Sports</category>
  <category lang="en">Basketball</category>
  <length units="minutes">120</length>
  <icon src="https://zap2it.tmsimg.com/assets/p14464724_tb2_v5_aa.jpg"/>
  <url>https://tvlistings.zap2it.com//overview.html?programSeriesId=SP00371600&amp;tmsId=SP003716000000</url>
  <episode-num system="dd_progid">SP00371600.0000</episode-num>
  <new/>
  <subtitles type="teletext"/>
</programme>
© www.soinside.com 2019 - 2024. All rights reserved.