Your absolute best option, imo would be to use PHP's native DOMDocument: http://php.net/manual/en/class.domdocument.php
There's quite a learning curve to this so I worked up something that should get you going in the right direction - if not provide a solution altogether. I've included line by line comments here to explain each step:
// the filename you want to parse
$filename = './test.html';
// an array of replacement html snippets and the id of the child element.
// html will be inserted before parent of each child with a matching ID as you described
$replacements = [
[
'id' => 'myId',
'insert' => '<button>Insert before parent of #myId</button>'
],
[
'id' => 'myId2',
'insert' => '<button>Insert before parent of#myId2</button>'
]
];
// instantiate DOMDocument and read the html file
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTMLFile('./test.html');
// get an array of all dom elements
$elements = $dom->getElementsByTagName('*');
// iterate through dom elements
foreach($elements as $element) {
// check if this element has an 'id' attribute
if ($element->hasAttribute('id')) {
// iterate through replacement array
foreach ($replacements as $i => $replacement) {
// if element's id is a match then add this node to our array
if ($element->getAttribute('id') == $replacement['id']) {
$replacements[$i]['nodes'][] = $element;
}
}
}
}
// iterate through replacements again
foreach ($replacements as $replacement) {
// iterate through nodes we found which matched
foreach ($replacement['nodes'] as $node) {
// create a DOMDocument node from an html string
$html = $dom->createDocumentFragment();
$html->appendXML($replacement['insert']);
// insert this node before parent
$node->parentNode->parentNode->insertBefore($html,$node->parentNode);
}
}
// output the revised html
echo $dom->saveHTML();
// note - if your html doesn't have <html> and <body> tags they will be automatically added by DOMDOcument
// you can work around this and get only body innerhtml with something like this
echo str_replace(['<body>','</body>'],'',$dom->saveHTML($dom->getElementsByTagName('body')->item(0)));
I created a test document with the following html called test.html. I intentionally used myId
twice to demonstrate that this will in fact match every element regardless of validity:
<div> // no tags no info just a simple div
<div id="myId">
... some html
</div>
</div>
<div> // no tags no info just a simple div
<div id="myId2">
... some html
</div>
</div>
<div> // no tags no info just a simple div
<div id="myId">
... some html
</div>
</div>
The php code above outputs the following:
<button>Insert before parent of #myId</button><div> // no tags no info just a simple div
<div id="myId">
... some html
</div>
</div>
<button>Insert before parent of #myId2</button><div> // no tags no info just a simple div
<div id="myId2">
... some html
</div>
</div>
<button>Insert before parent of #myId</button><div> // no tags no info just a simple div
<div id="myId">
... some html
</div>
</div>