我试图用DOMDocument用PHP中的XML部分生成一些XML,并且我需要附加两个XML部分。
我有两个以名称分隔的XML部分。一个用于带数据的“信封”,另一个用于循环数据,我需要将它们放在一起。将循环的数据放入信封。
我已经从StackOverflow尝试了很多示例,但是它们没有提到如何使用名称空间。
让我们看一些示例:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:aut="http://www.domain.xy/OSB/Authentication/"
xmlns:sch="http://www.domain.xy/schedule/ScheduleManager/"
xmlns:urn="urn:entsoe.eu:edi:ess:schedulemessage:3:3">
<soapenv:Header>
<aut:mekAuth>
<username>username</username>
<password>p455w0rd</password>
</aut:mekAuth>
</soapenv:Header>
<soapenv:Body>
<sch:receiveScheduleRequest>
<urn:ScheduleMessage DtdVersion="3" DtdRelease="3">
<urn:MessageIdentification v="xyz"/>
<urn:MessageVersion v="34"/>
<urn:MessageType v="xyz"/>
<urn:ProcessType v="xyz"/>
<urn:ScheduleClassificationType v="xyz"/>
<urn:SenderIdentification v="xyz" codingScheme="xyz"/>
<urn:SenderRole v="xyz"/>
<urn:ReceiverIdentification v="xyz" codingScheme="xyz"/>
<urn:ReceiverRole v="xyz"/>
<urn:MessageDateTime v="2019-06-23T23:23:28Z"/>
<urn:ScheduleTimeInterval v="2019-06-22T22:00Z/2019-06-23T22:00Z"/>
/* PART 2 WILL GOES HERE */
</urn:ScheduleMessage>
</sch:receiveScheduleRequest>
</soapenv:Body>
</soapenv:Envelope>
<urn:ScheduleTimeSeries>
<urn:SendersTimeSeriesIdentification v="xyz"/>
<urn:SendersTimeSeriesVersion v="34"/>
<urn:BusinessType v="xyz"/>
<urn:Product v="xyz"/>
<urn:ObjectAggregation v="xyz"/>
<urn:InArea v="xyz" codingScheme="xyz"/>
<urn:MeteringPointIdentification v="xyz codingScheme="xyz"/>
<urn:InParty v="xyz" codingScheme="xyz"/>
<urn:MeasurementUnit v="KWT"/>
/* PART 3 WILL GOES HERE */
</urn:ScheduleTimeSeries>
<urn:Period>
<urn:TimeInterval v="2019-06-22T22:00Z/2019-06-23T22:00Z"/>
<urn:Resolution v="PT15M"/>
<urn:Interval >
<urn:Pos v="1"/>
<urn:Qty v="0"/>
</urn:Interval>
<urn:Interval >
<urn:Pos v="2"/>
<urn:Qty v="0"/>
</urn:Interval>
<urn:Interval >
<urn:Pos v="3"/>
<urn:Qty v="0"/>
</urn:Interval>
<urn:Interval >
<urn:Pos v="4"/>
<urn:Qty v="0"/>
</urn:Interval>
</urn:Period>
我需要这样做:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:aut="http://www.domain.xy/OSB/Authentication/"
xmlns:sch="http://www.domain.xy/schedule/ScheduleManager/"
xmlns:urn="urn:entsoe.eu:edi:ess:schedulemessage:3:3">
<soapenv:Header>
<aut:mekAuth>
<username>username</username>
<password>p455w0rd</password>
</aut:mekAuth>
</soapenv:Header>
<soapenv:Body>
<sch:receiveScheduleRequest>
<urn:ScheduleMessage DtdVersion="3" DtdRelease="3">
<urn:MessageIdentification v="xyz"/>
<urn:MessageVersion v="34"/>
<urn:MessageType v="xyz"/>
<urn:ProcessType v="xyz"/>
<urn:ScheduleClassificationType v="xyz"/>
<urn:SenderIdentification v="xyz" codingScheme="xyz"/>
<urn:SenderRole v="xyz"/>
<urn:ReceiverIdentification v="xyz" codingScheme="xyz"/>
<urn:ReceiverRole v="xyz"/>
<urn:MessageDateTime v="2019-06-23T23:23:28Z"/>
<urn:ScheduleTimeInterval v="2019-06-22T22:00Z/2019-06-23T22:00Z"/>
<urn:ScheduleTimeSeries>
<urn:SendersTimeSeriesIdentification v="xyz"/>
<urn:SendersTimeSeriesVersion v="34"/>
<urn:BusinessType v="xyz"/>
<urn:Product v="xyz"/>
<urn:ObjectAggregation v="xyz"/>
<urn:InArea v="xyz" codingScheme="xyz"/>
<urn:MeteringPointIdentification v="xyz" codingScheme="xyz"/>
<urn:InParty v="xyz" codingScheme="xyz"/>
<urn:MeasurementUnit v="KWT"/>
<urn:Period>
<urn:TimeInterval v="2019-06-22T22:00Z/2019-06-23T22:00Z"/>
<urn:Resolution v="PT15M"/>
<urn:Interval >
<urn:Pos v="1"/>
<urn:Qty v="0"/>
</urn:Interval>
<urn:Interval >
<urn:Pos v="2"/>
<urn:Qty v="0"/>
</urn:Interval>
<urn:Interval >
<urn:Pos v="3"/>
<urn:Qty v="0"/>
</urn:Interval>
<urn:Interval >
<urn:Pos v="4"/>
<urn:Qty v="0"/>
</urn:Interval>
</urn:Period>
</urn:ScheduleTimeSeries>
</urn:ScheduleMessage>
</sch:receiveScheduleRequest>
</soapenv:Body>
</soapenv:Envelope>
public function generate_positions( $data, $res = "daily" )
{
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->xmlStandalone = true;
$dom->formatOutput = true;
$period = $dom->createElement("urn:Period");
$period = $dom->appendChild( $period );
$timeInterval = $dom->createElement("urn:TimeInterval");
// $timeInterval->setAttribute("v", $data->interval);
$timeInterval = $period->appendChild( $timeInterval );
$resolution = $dom->createElement("urn:Resolution");
$resolution->setAttribute("v", $time_resolution[$res]);
$resolution = $period->appendChild( $resolution );
foreach ( $data as $key => $value )
{
$interval = $dom->createElement("urn:Interval");
$interval = $period->appendChild( $interval );
$pos = $dom->createElement("urn:Pos");
$pos->setAttribute("v", $value["pos"]);
$pos = $interval->appendChild($pos);
$qty = $dom->createElement("urn:Qty");
$qty->setAttribute("v", $value["value"]);
$qty = $interval->appendChild($qty);
}
return $dom->saveXML( $period );
}
我想编写第二部分的generate函数,例如 generate_positions() 函数,但是我不知道如何从中“粘贴”返回的xml generate_positions
我尝试使用appendXML($ inner_xml),但通常收到以下错误消息:
消息:DOMDocumentFragment :: appendXML():名称空间错误:未定义Period上的命名空间前缀urn
我有名称空间声明,但在这种情况下我不知道在哪里使用
答案 0 :(得分:1)
首先,您需要正确生成XML片段并避免错误:
命名空间错误:未定义Period上的命名空间前缀urn
要合并名称空间前缀,请使用createElementNS()
而不是createElement()
:
$urn_uri = "urn:entsoe.eu:edi:ess:schedulemessage:3:3";
$period = $dom->createElementNS(urn_uri, "urn:Period");
$timeInterval = $dom->createElementNS(urn_uri, "urn:TimeInterval");
$resolution = $dom->createElementNS(urn_uri, "urn:Resolution");
...
正确生成每个片段后,请考虑XSLT(一种用于转换XML文件的专用语言),因为它维护document()
函数以从外部XML文件进行解析。 PHP可以使用其php/xsl库运行XSLT 1.0脚本(可能需要启用扩展名)。
下面假定名称空间已在第二个和第三个片段的根中正确定义。 注意:如果片段格式不正确,此XSLT解决方案将无法使用。
XSLT (另存为.xsl文件,一个特殊的.xml文件)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:aut="http://www.domain.xy/OSB/Authentication/"
xmlns:sch="http://www.domain.xy/schedule/ScheduleManager/"
xmlns:urn="urn:entsoe.eu:edi:ess:schedulemessage:3:3">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="urn:ScheduleMessage">
<xsl:copy>
<xsl:apply-templates select="*"/>
<xsl:apply-templates select="document('2nd Part.xml')/urn:ScheduleTimeSeries"/>
</xsl:copy>
</xsl:template>
<xsl:template match="urn:ScheduleTimeSeries">
<xsl:copy>
<xsl:apply-templates select="*"/>
<xsl:copy-of select="document('3rd Part.xml')/*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
PHP (仅在第一部分运行转换)
// LOAD XML AND XSLT
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load('1st Part.xml');
$xsl = new DOMDocument('1.0', 'UTF-8');
$xsl->load('Script.xsl');
// INITIALIZE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// RUN TRANSFORMATION
$newXML = $proc->transformToDoc($xml);
// ECHO TO CONSOLE
echo $newXML;
// SAVE TO FILE
file_put_contents('Output.xml', $newXML);
输出
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://www.domain.xy/OSB/Authentication/" xmlns:sch="http://www.domain.xy/schedule/ScheduleManager/" xmlns:urn="urn:entsoe.eu:edi:ess:schedulemessage:3:3">
<soapenv:Header>
<aut:mekAuth>
<username>username</username>
<password>p455w0rd</password>
</aut:mekAuth>
</soapenv:Header>
<soapenv:Body>
<sch:receiveScheduleRequest>
<urn:ScheduleMessage>
<urn:MessageIdentification v="xyz" />
<urn:MessageVersion v="34" />
<urn:MessageType v="xyz" />
<urn:ProcessType v="xyz" />
<urn:ScheduleClassificationType v="xyz" />
<urn:SenderIdentification v="xyz" codingScheme="xyz" />
<urn:SenderRole v="xyz" />
<urn:ReceiverIdentification v="xyz" codingScheme="xyz" />
<urn:ReceiverRole v="xyz" />
<urn:MessageDateTime v="2019-06-23T23:23:28Z" />
<urn:ScheduleTimeInterval v="2019-06-22T22:00Z/2019-06-23T22:00Z" />
<urn:ScheduleTimeSeries>
<urn:SendersTimeSeriesIdentification v="xyz" />
<urn:SendersTimeSeriesVersion v="34" />
<urn:BusinessType v="xyz" />
<urn:Product v="xyz" />
<urn:ObjectAggregation v="xyz" />
<urn:InArea v="xyz" codingScheme="xyz" />
<urn:MeteringPointIdentification v="xyz" codingScheme="xyz" />
<urn:InParty v="xyz" codingScheme="xyz" />
<urn:MeasurementUnit v="KWT" />
<urn:Period>
<urn:TimeInterval v="2019-06-22T22:00Z/2019-06-23T22:00Z" />
<urn:Resolution v="PT15M" />
<urn:Interval>
<urn:Pos v="1" />
<urn:Qty v="0" />
</urn:Interval>
<urn:Interval>
<urn:Pos v="2" />
<urn:Qty v="0" />
</urn:Interval>
<urn:Interval>
<urn:Pos v="3" />
<urn:Qty v="0" />
</urn:Interval>
<urn:Interval>
<urn:Pos v="4" />
<urn:Qty v="0" />
</urn:Interval>
</urn:Period>
</urn:ScheduleTimeSeries>
</urn:ScheduleMessage>
</sch:receiveScheduleRequest>
</soapenv:Body>
</soapenv:Envelope>