0

I'm developing a PHP web API (using Laravel Lumen) that outputs XML but writing the XML structures and attributes is getting out of hand, is there a simple way to create a custom function that shortens the codebase?

I'm using PHP's $xml = new \XMLWriter(); and writing code such as:

$xml->startElement('DataStructure');
$xml->writeAttribute('version', "1.0");

What i would like to do is something like:

$xml->startElement('DataStructure');
$this->api_version();

where

function api_version() {
    $xml->writeAttribute('version', "1.0");
}

2 Answers2

0

You could inherit from XMLWriter to match your needs. You could add a method like addDatastructure() and then use it like so:

class ExtendedWriter extends XMLWriter {
    public function addDatastructure($version): self {
        $this->startElement('DataStructure');
        $this->writeAttribute('version', $version);

        return $this;
    }
}

// And use it like a so:
$writer = new ExtendedWriter;
$writer->addDatastructure($version);

You can add whatever functionality you need. This makes your creation less code but also adds re-useability.

Manuel Mannhardt
  • 2,191
  • 1
  • 17
  • 23
0

Here is another option that allows to add more data structures without adding all of the logic to XMLWriter.

First define an interface for your data structure classes:

interface XMLWritable {
    public function writeTo(XMLWriter $writer); 
}

Now add a method to an extended XMLWriter that can accept it. Additionally the constructor of the extended XMLWriter can do some bootstrapping:

class MyXMLWriter extends XMLWriter {

    public function __construct(
      string $uri = 'php://output', string $version = '1.0', string $encoding = 'UTF-8'
    ) {
        $this->openURI($uri);
        $this->setIndent(true);
        $this->startDocument($version, $encoding);
    }

    public function write(XMLWritable $item): self {
        $item->writeTo($this);
        return $this;
    }
}

Next you implement the interface into specific data classes or serializers. You can add classes as needed. The XMLWriter does not need to know about them.

class ExampleItem implements XMLWritable {

    private $_content;

    public function __construct(string $content) {
        $this->_content = $content;
    }

    public function writeTo(XMLWriter $writer) {
        $writer->writeElement('example', $this->_content);
    }
}

Using them looks like this:

$writer = new MyXMLWriter();
$writer->startElement('root');
$writer
  ->write(new ExampleItem('one'))
  ->write(new ExampleItem('two'));
$writer->endElement();
ThW
  • 19,120
  • 3
  • 22
  • 44
  • Are you able to possibly reverse engineer a clear problem statement for [this question](https://stackoverflow.com/q/308703/2943403) based on [this self-answer](https://stackoverflow.com/a/308757/2943403) ? I don't have any knowledge in this domain. Otherwise the whole page is a complete mess and should be deleted. – mickmackusa Apr 17 '23 at 23:33