Skip to content

Commit

Permalink
Merge pull request #15 from slub/issue-2
Browse files Browse the repository at this point in the history
Issue 2
  • Loading branch information
dikastes authored Sep 9, 2024
2 parents e47507f + 443e317 commit 4758559
Show file tree
Hide file tree
Showing 8 changed files with 1,861 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ public/
typo3temp/
vendor/
composer.lock
Tests/Testfiles/*.json
157 changes: 150 additions & 7 deletions Classes/Common/XmlDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,173 @@

namespace Slub\LisztCommon\Common;

use SimpleXMLElement;

class XmlDocument
{

protected string $xmlString;

// Set up configuration vars
protected bool $includeLiteralString;
protected bool $includeXmlId;
protected array $splitSymbols;

// Private helper vars
protected array $convertedArray;

public function __construct(string $xmlString)
{
$this->xmlString = $xmlString;

// Deal with xml-reserved symbols
$this->xmlString = str_replace('&', '&', $this->xmlString);

// Default config
$this->includeLiteralString = false;
$this->includeXmlId = true;
$this->splitSymbols = array();
}

public static function from (string $xmlString): XmlDocument
// Set up config, if needed

public function setConfig(array $config)
{
$this->includeLiteralString = $config['literalString'];
$this->includeXmlId = $config['xmlId'];
$this->splitSymbols = $config['splitSymbols'];
return $this;
}

// Functions to set single config aspects

public function setXmlId(bool $xmlId)
{
$this->includeXmlId = $xmlId;
return $this;
}

public function setLiteralString(bool $literal)
{
$this->includeLiteralString = $literal;
return $this;
}

public function setSplitSymbols(array $splitSymbols)
{
$this->splitSymbols = $splitSymbols;
return $this;
}

public static function from(string $xmlString): XmlDocument
{
return new XmlDocument($xmlString);
}

public function toArray(): array
{
// add function here
return [];
// Check if array is already converted
if (isset($this->convertedArray)) {
return $this->convertedArray;
}

$this->convertedArray = [];
$xml = simplexml_load_string($this->xmlString);
$this->convertedArray[$this->getXmlId($xml)] = $this->convert($xml);
return $this->convertedArray;
}

public function toJson()
{
$result = [];
$xmlArray = $this->toArray();

/*
* Convert every key value pair to valid json,
* then decode it, so it stays valid when the whole
* array is encoded
*/
foreach ($xmlArray as $id => $value) {
$result[$id] = json_encode($value);
$result[$id] = json_decode($result[$id], true);
}
return trim(json_encode($result));
}

protected function convert(SimpleXMLElement $node): array
{
$result = [];

// Parse attributes
$attrs = collect($node->attributes())->filter(function ($attrValue) {
return !empty(trim(strval($attrValue)));
})->mapWithKeys(function ($attrValue, $attrName) {
return [$attrName => trim((string) $attrValue)];
})->toArray();

// Merge parsed attributes with result array
if (!empty($attrs)) {
$result = array_merge_recursive($result, ['@attributes' => $attrs]);
}

// Parse value
$nodeValue = trim((string) $node);
if (!empty($nodeValue)) {
$result['@value'] = $nodeValue;
}

// Include xml:id attribute
if ($this->includeXmlId) {
$xmlId = $node->attributes('xml', true)->id;
$trimmedXmlId = trim(strval($xmlId));
if (!empty($trimmedXmlId)) {
$result['@xml:id'] = $trimmedXmlId;
}
}

// Check if node is a mixed-content element (if literalString is set to true)

if ($this->includeLiteralString) {
if ($node->getName() == 'p' && $node->count() > 0 && !empty($node)) {
// Add literal string, to store the node order
$literal = str_replace(array("\n", "\r"), '', trim($node->asXML()));
$literal = str_replace('<?xml version="1.0"?>', '', $literal);
$result['@literal'] = $literal;
}
}

$toParse = collect($node->children())->filter(function ($subject) use ($node, &$result) {
foreach ($this->splitSymbols as $symbol) {
if ($subject->getName() == $symbol) {
$result['@link'] = $this->getXmlId($subject);
$this->convertedArray[$this->getXmlId($subject)] = $this->convert($subject);
return false;
}
}
return true;
});

$toParse->each(function ($subject) use (&$result) {
$result = $this->parseChild($subject, $result);
});

return $result;
}

private function parseChild(SimpleXMLElement $child, array $result)
{
$childName = $child->getName();
$childData = $this->convert($child);
// Always parse child nodes as array
if (!isset($result[$childName])) {
$result[$childName] = [];
}
$result[$childName][] = $childData;

return $result;
}

public function toJson(): string
private function getXmlId(SimpleXMLElement $xml)
{
// add function here
return '';
return strval($xml->attributes('xml', true)->id);
}
}
41 changes: 30 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,38 @@ This comprises the elasticsearch connection and translation of file formats.

You can obtain a Controller with easy access to elasticsearch by inheriting from ClientEnabledController.

use Slub\LisztCommon\Controller\ClientEnabledController;
```php
use Slub\LisztCommon\Controller\ClientEnabledController;

class ActionController extends ClientEnabledController
{
class ActionController extends ClientEnabledController
{

public function ExampleAction()
{
$this->initializeClient();
$params = ...
$entity = $this->elasticClient->search($params);
...
public function ExampleAction()
{
$this->initializeClient();
$params = ...
$entity = $this->elasticClient->search($params);
...

}
}

}
}
```
## Translation between XML and JSON

You can read in an XML document and translate it to a PHP array or JSON.

```php
use Slub\LisztCommon\Common\XmlDocument;
...

$xmlDocument = XmlDocument::from($xmlString);
$array = $xmlDocument->toArray();
$json = $xmlDocument->toJson();
```

# Maintainer

If you have any questions or encounter any problems, please do not hesitate to contact me.
- [Matthias Richter](https://github.com/dikastes)
2 changes: 1 addition & 1 deletion Tests/Functional/Common/Fixtures/minimal.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"minimal_root":{"@xml:id":"minimal_root","subroot":[{"subsubroot":[{"@value":"entry"}]}]}}
10 changes: 9 additions & 1 deletion Tests/Functional/Common/Fixtures/minimal.xml
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@

<?xml version="1.0" encoding="UTF-8"?>
<root xml:id="minimal_root">
<subroot>
<subsubroot>
entry
</subsubroot>
</subroot>

</root>
Loading

0 comments on commit 4758559

Please sign in to comment.