John's Technical Blog

Creating and Nesting SimpleXMLElement Objects in PHP

2023-06-15

Introduction

When working with XML data in PHP, the SimpleXMLElement class provides a convenient way to create and manipulate XML structures. One common requirement is to create a SimpleXMLElement and add it as a child to another SimpleXMLElement. In this blog post, we'll explore the correct solution to achieve this.

Creating the Parent and Child Elements

/* Create the parent SimpleXMLElement */
$parent = new SimpleXMLElement('<parent></parent>');

/* Create the child SimpleXMLElement */
$child = new SimpleXMLElement('<child></child>');

Adding Content to the Child Element

$child->addChild('name', 'John');
$child->addChild('age', 25);

Importing and Nesting the Child Element

Now comes the crucial part: importing and nesting the child element within the parent element. We'll use the dom_import_simplexml() function to convert the SimpleXMLElement objects to DOMNode objects. Here's how it's done:

$domChild = dom_import_simplexml($child);
$domParent = dom_import_simplexml($parent);
$domChild = $domParent->ownerDocument->importNode($domChild, true);
$domParent->appendChild($domChild);

In the above code, we import the child element into the parent element's document using the importNode() method. The second argument true indicates that we want to import the entire subtree of the child node.

Printing the Final XML Structure

To see the final XML structure, we can call the asXML() method on the parent element:

echo $parent->asXML();

This will output the complete XML structure, including the parent and nested child elements.

The xmlAdopt() Method

To simplify the process of adopting a child element into a parent element, we can use a helper method called xmlAdopt():

/**
 * Adopt a SimpleXMLElement into another SimpleXMLElement.
 *
 * @param SimpleXMLElement $parent the parent element
 * @param SimpleXMLElement $child  the child element to add to the parent
 */
private function xmlAdopt(SimpleXMLElement $parent, SimpleXMLElement $child): void
{
    $domChild = dom_import_simplexml($child);
    $domParent = dom_import_simplexml($parent);
    $domChild = $domParent->ownerDocument->importNode($domChild, true);
    $domParent->appendChild($domChild);
}

Using the xmlAdopt() Method:

$this->xmlAdopt($parent, $child);

Conclusion:

Creating and nesting SimpleXMLElement objects in PHP requires careful handling

MySQL AES Encryption in Ruby

2018-05-14

I was asked to find a way to encrypt strings in Ruby that would be compatible with MySQL's AES_ENCRYPT and AES_DECRYPT functions. I found several solutions online, but none of them worked the way I expected. After cobbling together several examples, I finally came up with a solution that proved to be compatible with the MySQL version. This was written for use with Ruby 2.3.5. This module can be used as follows:

Running a Tomcat-based Spring Boot application in Docker

2018-05-01

In one of the projects I am working on, I was tasked from taking a Tomcat application that ran on an EC2 server, and get it running with the Spring Boot framework in a Docker container. The twist is that the application needed read-write access to the resources folder within the project. In order to do that, the application needed to be run as an "exploded" WAR file (It had been run that way on the old server as well).

I accomplished this with this Docker file:

The WAR file is compiled with the "spring-boot-maven-plugin", and includes all the dependency JARs, so the application can be run stand-alone.

That entry in the POM is:

And the "org.springframework.boot.loader.WarLauncher" Class is what Spring Boot uses to bootstrap the applicatiton on the embedded Tomcat.

OpenPojo Java 9 Compatibility Workaround

2017-11-02

I am working on updating applications at work to Java 9. I have been using OpenPojo for years to test all my POJOs in one go. However, I found that the tests started throwing the exception:

java.lang.NoClassDefFoundError: Could not initialize class com.openpojo.reflection.java.packageloader.Package

I traced through the OpenPojo code and found that it was hard coded to read the Java class path from the old "sun.boot.class.path" system property. This property has been completely removed from Java 9, in favor of "java.class.path," which has been available since at least Java 7. (See https://docs.oracle.com/javase/8/docs/technotes/tools/windows/findingclasses.html)

I submitted my findings in an issue for the developers consideration: https://github.com/oshoukry/openpojo/issues/108

In the meantime, I developed the following workaround that can be inserted into a current POJO test class, and will allow the code to function the same way in Java 9.

Find All the Divisors for a Number

2017-08-07

In some of my load testing, I want to run a certain number of transactions. My script takes parameters for a number of threads and the number of loops all the threads should go to. When I have a certain target number I want to get to, and an idea of what number of threads I want, I would like to figure out exactly how many loops I need to run for an exact number of threads.

For example, lets say I want to process 16,000,000 transactions with about 300 threads. I can run the following Java class, and figure out that if I use 320 threads, I need 50,000 loops.




Enter an integer: 16000000
Even divisors for 16000000
8000000 x 2 = 16000000
4000000 x 4 = 16000000
3200000 x 5 = 16000000
2000000 x 8 = 16000000
1600000 x 10 = 16000000
1000000 x 16 = 16000000
800000 x 20 = 16000000
640000 x 25 = 16000000
500000 x 32 = 16000000
400000 x 40 = 16000000
320000 x 50 = 16000000
250000 x 64 = 16000000
200000 x 80 = 16000000
160000 x 100 = 16000000
128000 x 125 = 16000000
125000 x 128 = 16000000
100000 x 160 = 16000000
80000 x 200 = 16000000
64000 x 250 = 16000000
62500 x 256 = 16000000
50000 x 320 = 16000000
40000 x 400 = 16000000
32000 x 500 = 16000000
31250 x 512 = 16000000
25600 x 625 = 16000000
25000 x 640 = 16000000
20000 x 800 = 16000000
16000 x 1000 = 16000000
15625 x 1024 = 16000000
12800 x 1250 = 16000000
12500 x 1280 = 16000000
10000 x 1600 = 16000000
8000 x 2000 = 16000000
6400 x 2500 = 16000000
6250 x 2560 = 16000000
5120 x 3125 = 16000000
5000 x 3200 = 16000000
4000 x 4000 = 16000000
3200 x 5000 = 16000000
3125 x 5120 = 16000000
2560 x 6250 = 16000000
2500 x 6400 = 16000000
2000 x 8000 = 16000000
1600 x 10000 = 16000000
1280 x 12500 = 16000000
1250 x 12800 = 16000000
1024 x 15625 = 16000000
1000 x 16000 = 16000000
800 x 20000 = 16000000
640 x 25000 = 16000000
625 x 25600 = 16000000
512 x 31250 = 16000000
500 x 32000 = 16000000
400 x 40000 = 16000000
320 x 50000 = 16000000
256 x 62500 = 16000000
250 x 64000 = 16000000
200 x 80000 = 16000000
160 x 100000 = 16000000
128 x 125000 = 16000000
125 x 128000 = 16000000
100 x 160000 = 16000000
80 x 200000 = 16000000
64 x 250000 = 16000000
50 x 320000 = 16000000
40 x 400000 = 16000000
32 x 500000 = 16000000
25 x 640000 = 16000000
20 x 800000 = 16000000
16 x 1000000 = 16000000
10 x 1600000 = 16000000
8 x 2000000 = 16000000
5 x 3200000 = 16000000
4 x 4000000 = 16000000
2 x 8000000 = 16000000
1 x 16000000 = 16000000
=== End ===

Essentially, this provides all the numbers that evenly divide the provided number. Or, in other words, find multipliers that will result in a desired product.