fix: skip blank xml nodes and attributes when anonymizing data
This commit is contained in:
@@ -336,24 +336,24 @@ class BpnXmlAnonymizer
|
||||
{
|
||||
$nameNode = $this->getDirectChild($personNode, 'name');
|
||||
if (null !== $nameNode) {
|
||||
$nameNode->nodeValue = $identity['lastName'];
|
||||
$this->replaceNodeValue($nameNode, $identity['lastName']);
|
||||
}
|
||||
|
||||
$firstNameNode = $this->getDirectChild($personNode, 'vorname');
|
||||
if (null !== $firstNameNode) {
|
||||
$firstNameNode->nodeValue = $identity['firstName'];
|
||||
$this->replaceNodeValue($firstNameNode, $identity['firstName']);
|
||||
}
|
||||
|
||||
if (true === $personNode->hasAttribute('name')) {
|
||||
$personNode->setAttribute('name', $identity['lastName']);
|
||||
$this->replaceAttributeValue($personNode, 'name', $identity['lastName']);
|
||||
}
|
||||
|
||||
if (true === $personNode->hasAttribute('vorname')) {
|
||||
$personNode->setAttribute('vorname', $identity['firstName']);
|
||||
$this->replaceAttributeValue($personNode, 'vorname', $identity['firstName']);
|
||||
}
|
||||
|
||||
if (true === $personNode->hasAttribute('id') && 'kunde' === $personNode->tagName) {
|
||||
$personNode->setAttribute('id', $identity['customerId']);
|
||||
$this->replaceAttributeValue($personNode, 'id', $identity['customerId']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,7 +367,7 @@ class BpnXmlAnonymizer
|
||||
if ('anfrage' === $personNode->tagName) {
|
||||
$emailNode = $this->getDirectChild($personNode, 'email');
|
||||
if (null !== $emailNode) {
|
||||
$emailNode->nodeValue = $identity['email'];
|
||||
$this->replaceNodeValue($emailNode, $identity['email']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,22 +376,22 @@ class BpnXmlAnonymizer
|
||||
|
||||
$emailNode = $this->getDirectChild($communicationNode, 'email');
|
||||
if (null !== $emailNode) {
|
||||
$emailNode->nodeValue = $identity['email'];
|
||||
$this->replaceNodeValue($emailNode, $identity['email']);
|
||||
}
|
||||
|
||||
$mobileNode = $this->getDirectChild($communicationNode, 'telefonmobil');
|
||||
if (null !== $mobileNode) {
|
||||
$mobileNode->nodeValue = $identity['mobilePhone'];
|
||||
$this->replaceNodeValue($mobileNode, $identity['mobilePhone']);
|
||||
}
|
||||
|
||||
$phoneNode = $this->getDirectChild($communicationNode, 'telefonprivat');
|
||||
if (null !== $phoneNode) {
|
||||
$phoneNode->nodeValue = $identity['phone'];
|
||||
$this->replaceNodeValue($phoneNode, $identity['phone']);
|
||||
}
|
||||
|
||||
$newsletterNode = $this->getDirectChild($communicationNode, 'newsletter');
|
||||
if (null !== $newsletterNode) {
|
||||
$newsletterNode->nodeValue = $identity['newsletter'];
|
||||
$this->replaceNodeValue($newsletterNode, $identity['newsletter']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,32 +407,32 @@ class BpnXmlAnonymizer
|
||||
|
||||
$streetNode = $this->getDirectChild($addressNode, 'strasse');
|
||||
if (null !== $streetNode) {
|
||||
$streetNode->nodeValue = $identity['street'];
|
||||
$this->replaceNodeValue($streetNode, $identity['street']);
|
||||
}
|
||||
|
||||
$postalCodeNode = $this->getDirectChild($addressNode, 'plz');
|
||||
if (null !== $postalCodeNode) {
|
||||
$postalCodeNode->nodeValue = $identity['postalCode'];
|
||||
$this->replaceNodeValue($postalCodeNode, $identity['postalCode']);
|
||||
}
|
||||
|
||||
$cityNode = $this->getDirectChild($addressNode, 'ort');
|
||||
if (null !== $cityNode) {
|
||||
$cityNode->nodeValue = $identity['city'];
|
||||
$this->replaceNodeValue($cityNode, $identity['city']);
|
||||
}
|
||||
|
||||
$districtNode = $this->getDirectChild($addressNode, 'ortsteil');
|
||||
if (null !== $districtNode) {
|
||||
$districtNode->nodeValue = $identity['district'];
|
||||
$this->replaceNodeValue($districtNode, $identity['district']);
|
||||
}
|
||||
|
||||
$countryNode = $this->getDirectChild($addressNode, 'land');
|
||||
if (null !== $countryNode) {
|
||||
$countryNode->nodeValue = $identity['country'];
|
||||
$this->replaceNodeValue($countryNode, $identity['country']);
|
||||
}
|
||||
|
||||
$addressIdNode = $this->getDirectChild($addressNode, 'id');
|
||||
if (null !== $addressIdNode) {
|
||||
$addressIdNode->nodeValue = $identity['addressId'];
|
||||
$this->replaceNodeValue($addressIdNode, $identity['addressId']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,42 +440,42 @@ class BpnXmlAnonymizer
|
||||
{
|
||||
$salutationNode = $this->getDirectChild($personNode, 'anrede');
|
||||
if (null !== $salutationNode) {
|
||||
$salutationNode->nodeValue = $identity['salutation'];
|
||||
$this->replaceNodeValue($salutationNode, $identity['salutation']);
|
||||
}
|
||||
|
||||
$titleNode = $this->getDirectChild($personNode, 'titel');
|
||||
if (null !== $titleNode) {
|
||||
$titleNode->nodeValue = $identity['title'];
|
||||
$this->replaceNodeValue($titleNode, $identity['title']);
|
||||
}
|
||||
|
||||
$genderNode = $this->getDirectChild($personNode, 'geschlecht');
|
||||
if (null !== $genderNode) {
|
||||
$genderNode->nodeValue = $identity['gender'];
|
||||
$this->replaceNodeValue($genderNode, $identity['gender']);
|
||||
}
|
||||
|
||||
$nationalityNode = $this->getDirectChild($personNode, 'nationalitaet');
|
||||
if (null !== $nationalityNode) {
|
||||
$nationalityNode->nodeValue = $identity['nationality'];
|
||||
$this->replaceNodeValue($nationalityNode, $identity['nationality']);
|
||||
}
|
||||
|
||||
$birthDateNode = $this->getDirectChild($personNode, 'geburtsdatum');
|
||||
if (null !== $birthDateNode) {
|
||||
$birthDateNode->nodeValue = $identity['birthDate'];
|
||||
$this->replaceNodeValue($birthDateNode, $identity['birthDate']);
|
||||
}
|
||||
|
||||
$heightNode = $this->getDirectChild($personNode, 'sonstiges1');
|
||||
if (null !== $heightNode) {
|
||||
$heightNode->nodeValue = $identity['height'];
|
||||
$this->replaceNodeValue($heightNode, $identity['height']);
|
||||
}
|
||||
|
||||
$weightNode = $this->getDirectChild($personNode, 'sonstiges2');
|
||||
if (null !== $weightNode) {
|
||||
$weightNode->nodeValue = $identity['weight'];
|
||||
$this->replaceNodeValue($weightNode, $identity['weight']);
|
||||
}
|
||||
|
||||
$shoeSizeNode = $this->getDirectChild($personNode, 'sonstiges3');
|
||||
if (null !== $shoeSizeNode) {
|
||||
$shoeSizeNode->nodeValue = $identity['shoeSize'];
|
||||
$this->replaceNodeValue($shoeSizeNode, $identity['shoeSize']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,7 +488,7 @@ class BpnXmlAnonymizer
|
||||
|
||||
$ibanNode = $this->getDirectChild($bankNode, 'iban');
|
||||
if (null !== $ibanNode) {
|
||||
$ibanNode->nodeValue = $identity['iban'];
|
||||
$this->replaceNodeValue($ibanNode, $identity['iban']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,9 +496,9 @@ class BpnXmlAnonymizer
|
||||
{
|
||||
if (true === $personNode->hasAttribute('id')) {
|
||||
if ('kunde' === $personNode->tagName) {
|
||||
$personNode->setAttribute('id', $identity['customerId']);
|
||||
$this->replaceAttributeValue($personNode, 'id', $identity['customerId']);
|
||||
} elseif ('teilnehmer' === $personNode->tagName || 'anmelder' === $personNode->tagName) {
|
||||
$personNode->setAttribute('id', $identity['personId']);
|
||||
$this->replaceAttributeValue($personNode, 'id', $identity['personId']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -507,25 +507,43 @@ class BpnXmlAnonymizer
|
||||
{
|
||||
$userNode = $this->getDirectChild($personNode, 'user');
|
||||
if (null !== $userNode) {
|
||||
$userNode->nodeValue = $identity['userName'];
|
||||
$this->replaceNodeValue($userNode, $identity['userName']);
|
||||
}
|
||||
|
||||
$keyNode = $this->getDirectChild($personNode, 'key');
|
||||
if (null !== $keyNode) {
|
||||
$keyNode->nodeValue = $identity['requestKey'];
|
||||
$this->replaceNodeValue($keyNode, $identity['requestKey']);
|
||||
}
|
||||
|
||||
$emailNode = $this->getDirectChild($personNode, 'email');
|
||||
if (null !== $emailNode) {
|
||||
$emailNode->nodeValue = $identity['email'];
|
||||
$this->replaceNodeValue($emailNode, $identity['email']);
|
||||
}
|
||||
|
||||
$passwordNode = $this->getDirectChild($personNode, 'passwort');
|
||||
if (null !== $passwordNode) {
|
||||
$passwordNode->nodeValue = $identity['requestPassword'];
|
||||
$this->replaceNodeValue($passwordNode, $identity['requestPassword']);
|
||||
}
|
||||
}
|
||||
|
||||
private function replaceNodeValue(\DOMElement $node, string $replacement): void
|
||||
{
|
||||
if ('' === trim($node->textContent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$node->nodeValue = $replacement;
|
||||
}
|
||||
|
||||
private function replaceAttributeValue(\DOMElement $node, string $attributeName, string $replacement): void
|
||||
{
|
||||
if ('' === trim((string) $node->getAttribute($attributeName))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$node->setAttribute($attributeName, $replacement);
|
||||
}
|
||||
|
||||
private function findAncestorDirectChild(\DOMElement $personNode, string $ancestorTagName, string $childTagName): ?\DOMElement
|
||||
{
|
||||
$currentNode = $personNode;
|
||||
|
||||
@@ -236,6 +236,85 @@ XML;
|
||||
$this->assertSame('900002', $secondCustomerId);
|
||||
}
|
||||
|
||||
public function testAnonymizePreservesEmptyNodesAndAttributes(): void
|
||||
{
|
||||
$xml = <<<'XML'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<anfrage>
|
||||
<user></user>
|
||||
<key/>
|
||||
<email> </email>
|
||||
<passwort></passwort>
|
||||
<anmelder id="">
|
||||
<name/>
|
||||
<vorname> </vorname>
|
||||
<anrede></anrede>
|
||||
<geschlecht>W</geschlecht>
|
||||
<nationalitaet></nationalitaet>
|
||||
<geburtsdatum/>
|
||||
<anschrift>
|
||||
<id></id>
|
||||
<strasse/>
|
||||
<plz>12345</plz>
|
||||
<ort> </ort>
|
||||
<land></land>
|
||||
</anschrift>
|
||||
<kommunikation>
|
||||
<email></email>
|
||||
<telefonmobil>01701234567</telefonmobil>
|
||||
<telefonprivat/>
|
||||
<newsletter></newsletter>
|
||||
</kommunikation>
|
||||
<bankverbindung>
|
||||
<iban></iban>
|
||||
</bankverbindung>
|
||||
<sonstiges1/>
|
||||
<sonstiges2>75</sonstiges2>
|
||||
<sonstiges3></sonstiges3>
|
||||
</anmelder>
|
||||
<kundennamen>
|
||||
<kunde id="" art="Teilnehmer" name="" vorname="Ada"/>
|
||||
</kundennamen>
|
||||
</anfrage>
|
||||
XML;
|
||||
|
||||
$anonymizer = new BpnXmlAnonymizer();
|
||||
$result = $anonymizer->anonymize($xml);
|
||||
|
||||
$document = new \DOMDocument();
|
||||
$this->assertTrue($document->loadXML($result));
|
||||
|
||||
$xpath = new \DOMXPath($document);
|
||||
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(/anfrage/user)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(/anfrage/key)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(/anfrage/email)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(/anfrage/passwort)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/@id)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/name)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/vorname)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/anrede)')));
|
||||
$this->assertSame('D', trim((string) $xpath->evaluate('string(//anmelder/geschlecht)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/nationalitaet)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/geburtsdatum)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/anschrift/id)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/anschrift/strasse)')));
|
||||
$this->assertNotSame('12345', trim((string) $xpath->evaluate('string(//anmelder/anschrift/plz)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/anschrift/ort)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/anschrift/land)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/kommunikation/email)')));
|
||||
$this->assertSame('01000000002', trim((string) $xpath->evaluate('string(//anmelder/kommunikation/telefonmobil)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/kommunikation/telefonprivat)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/kommunikation/newsletter)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/bankverbindung/iban)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/sonstiges1)')));
|
||||
$this->assertSame('70', trim((string) $xpath->evaluate('string(//anmelder/sonstiges2)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//anmelder/sonstiges3)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//kundennamen/kunde/@id)')));
|
||||
$this->assertSame('', trim((string) $xpath->evaluate('string(//kundennamen/kunde/@name)')));
|
||||
$this->assertNotSame('Ada', trim((string) $xpath->evaluate('string(//kundennamen/kunde/@vorname)')));
|
||||
}
|
||||
|
||||
public function testAnonymizeThrowsOnInvalidXml(): void
|
||||
{
|
||||
$anonymizer = new BpnXmlAnonymizer();
|
||||
|
||||
Reference in New Issue
Block a user