Aqui está uma maneira de resolver o problema. Ele não codifica nenhum dos nomes de nó filho (
TI
, MO
, AU
, etc.) para que você possa usá-lo em documentos semelhantes. Eu coloquei comentários no código, então leia-os e pergunte se você não entende o que o código está fazendo. $txt = 'your XML string goes here';
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($txt);
$xp = new DOMXPath($dom);
# find all the nodes types that appear under Record
$cnode_type = array();
foreach ($xp->query("/Results/Recordset/Record/*") as $c) {
$cnode_type[] = $c->nodeName;
}
# cnode_type now contains the different child node types
$cnode_type = array_unique($cnode_type);
# get all the Record nodes
$recs = $xp->query("/Results/Recordset/Record");
# for every Record node...
foreach ($recs as $par) {
# for each type of child node...
foreach ($cnode_type as $c) {
# run an XPath query to count the number of children of node type $c
# if there are more than one, we need to remove the extras
if ($xp->evaluate("count($c)", $par) > 1) {
# go through all the $c nodes, saving the value in $node_vals
# delete the node
$node_vals = [];
foreach ($xp->query($c, $par) as $n) {
# only save the contents of nodes with a value
if (isset($n->nodeValue) && strlen($n->nodeValue) > 0) {
$node_vals[] = $n->nodeValue;
}
$par->removeChild($n);
}
# create a new $c node and set the value to the list in $node_vals
# add it to the parent node
$new_node = $dom->createElement($c, implode("; ", $node_vals));
$par->appendChild($new_node);
}
}
}
# print out the result
echo $dom->saveXML();
Saída do XML que você postou:
<?xml version="1.0"?>
<Results>
<Recordset setCount="3">
<Record setEntry="0">
<TI>Test-1</TI>
<MO>Mo-1</MO>
<JF>OK</JF>
<JT/>
<AU>One; Two; three</AU>
</Record>
<Record setEntry="1">
<TI>Test-2</TI>
<MO>Mo-2</MO>
<JF/>
<JT/>
<AU>One; Two; Three; Four; Five; Six; Seven</AU>
</Record>
<Record setEntry="2">
<TI>Test31</TI>
<MO>Mo-3</MO>
<JF/>
<JT/>
<AU>One</AU>
</Record>
</Recordset>
</Results>