简体   繁体   中英

How can I append an xml with namespaces to another xml in php, DOMDocument?

I'm trying to generate some XML with XML parts in PHP, with DOMDocument, and I need to append two XML parts.

I have two name-spaced XML parts. One for an "envelope" with datas, and one for looped datas, and I need to put these together. Put the looped datas to the envelope.

I've already tried a lot of examples from StackOverflow, but they do not mention how to do with namespaces.

First and foremost, you need to properly generate the XML fragments and avoid the error:

namespace error : Namespace prefix urn on Period is not defined

To incorporate namespace prefixes use createElementNS() instead of 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");

...

Once each fragment is properly generated, consider XSLT , the special-purpose language designed to transform XML files, since it maintains the document() function to parse from external XML files. PHP can run XSLT 1.0 scripts using its php/xsl library (might require enabling the extension).

Below assumes namespaces are properly defined in root of 2nd and 3rd fragments. NOTE : this XSLT solution will not work if fragments are not well-formed.

XSLT (save as .xsl file, a special .xml file)

<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 (run transformation only on first part)

// 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);

Output

<?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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM