[ Zlatni_bg @ 14.10.2021. 22:32 ] @
Pozdrav,

Imam situaciju da treba da obradjujem neke XML-ove, i desi se da nisu validni, moraju da se lupe CDATA tagovi jer ima nevalidnih karaktera.

Uspeo sam da napravim regex, isprobao na regex101, sve ful, medjutim, treba da po'vatam sve elemente koji imaju link u sebi... radim tako sto hvatam >http/s i menjam sadrzaj sa ><![CDATA[https://nekilink]]>, u fazonu:

<link>https:// ne valja</link>

<link><![CDATA[https:// link valja]]></link>

Evo ga regex:

preg_replace('#(\A|[^=\]\'"a-zA-Z0-9])(http[s]?://(.+\w)/[^()<>\n]+)#i', '\\1<![CDATA[\\2]]>', $file);

Naravno koliko znam, PHP ne potrzava multiline, tako da verovatno ne znam da ga pogodim. Valjalo bi mi neko elegantno i brzo resenje, bez previse manipulacije, brzina donekle moze i da ispasta zbog kraceg resenja jer imam mnooogo xml-ova koji imaju nekih problema, ovo je samo jedan od njih. Molim Boga da ne bude foreach ili nesto tako :)

P.S. "m" ne pomaze umesto i na kraju, a g nije podrzan od strane phpa :)

Hvala :)
[ Deunan @ 15.10.2021. 00:03 ] @
Treba da ih citas ili pravis?
Probaj ovako:
Code:

class SimpleXMLExtended extends SimpleXMLElement {
    public function addCData($cdata_text) {
        $node = dom_import_simplexml($this);
        $no   = $node->ownerDocument;
        $node->appendChild($no->createCDATASection($cdata_text));
    }
}

Onda kreiras XML:
Code:

$products = new SimpleXMLExtended('<?xml version="1.0" encoding="UTF-8"?><products/>');

$product = $products->addChild('product');
$product->naziv_proizvoda = NULL;  // obavezno prvo kreirati element
$product->naziv_proizvoda->addCData("IME PROIZVODA");
$product->link = NULL;
$product->link->addCData("https://example.com");

Header('Content-type: text/xml');
print($products->asXML());

[ Zlatni_bg @ 15.10.2021. 00:21 ] @
Ne mogu to da uradim jer XML nije validan :(

Cim ima "&" karakter van CDATA, ne moze da se ucita ni u jedan XML lib, bilo simplexml, DOC...

Potrebno mi je da ih citam. Fora je sto se koriste za nesto, da bi se koristili, moraju prvo da se ucitaju, simplexml zavrsava posao. Gomila eksternih faktora utice na sam XML i moram da ga obradim kako znam i umem, ovo je jedan scenario. Uspeo sam sa drugim regexom da uhvatim sve matcheve u stringu, ispostavilo se da sam pogresio da staje kod prvog vec nisam lepo ispisao regex.

Fora je sto kako prolazim kroz koji XML, vidim da ce svuda morati CDATA, u sve elemente, i da cu morati da hvatam sve vrednosti izmedju ">" i "</">, sto je mozda i lakse :)

Code:
preg_replace("#(?<=(url>))(\w|\d|\n|[().,\-:;@$%^&*\[\]'+–/®°⁰!?{}|`~]| )+?(?=(</))#", '<![CDATA[\\0]]>', $file); 


Ovako je trenutno, pola 2 ujutru je i bukvalno ne uspevam da uhvatim ">", sve je ok ako hvatam "url>"...
[ Deunan @ 15.10.2021. 00:39 ] @
Mozes da probas sa obicnim str_replace:
Code:

$xml = file_get_contents('test.xml');

$tags = ['link', 'tag1'];   // Tagovi koje treba da zamenis

foreach (tags  as $tag) {
    $xml = str_replace("<{$tag}>", "<{$tag}><![CDATA[", $xml);
    $xml = str_replace("</{$tag}>", "]]></{$tag}>", $xml);
}

$myfile = fopen("newfile.xml", "w");
fwrite($myfile, $xml);
fclose($myfile);

Posto svaki tag mora da prodje 2 puta, moze da bude malo zatevnije na vecim XML fajlovima.
[ Panta_ @ 15.10.2021. 06:38 ] @
Ako sam dobro razumeo šta želiš. Probaj ovako:
Code:
preg_replace('/<(\w+)[^>]*>(https?.*?)<\/\1>/', '<\1><![CDATA[\2]]></\1>', $file);


https://www.phpliveregex.com/p/Chb#tab-preg-replace
[ Zlatni_bg @ 24.10.2021. 05:04 ] @
Hvala puno momci. Preko regexa sam sredio stvar, sredio sam Pantin regex da hvata sve tagove, odlucio sam da se ne ogranicavam na URL-ove.

A ovaj foreach ce imati upotrebu u drugom delu, imam gooomilu lose formiranih XML-ova koji dinamicki moraju da se ispravljaju, pokusavam da napravim neki univerzalan servis jer se slucajevi ponavljaju.

Hvala jos jednom, zivi bili :)