Senaryonuz birçok kenar-durumlarda ve üstünde ekliyor gerektiğini kelime var. Klasik modelini yapmak istediğinizi varsayalım, bir çift ara, numaralı yeni bir paragrafı başlatır, ancak bu sefer ebeveynler <div>
(veya kesinlikle diğer blok öğeleri) içinde de geçerlidir.
İşin çoğunu HTML ayrıştırıcısına izin veririm, ancak yine de metin aramasıyla çalışır ve değiştiririm (xpath'in yanında). Gelecekte göreceğiniz şey biraz acelecidir ama bence oldukça kararlıdır:
Her şeyden önce, söz konusu divun üst düzey veya alt düzeyindeki tüm metin düğümlerini seçerdim.
(.|./div)/text()
Bu xpath DOMDocument
yüklenen zaman HTML parçasının kök-tag temsil ettiği <body>
etikettir bir çapa elemana göre olur.
Eğer bir divun çocuğuysa, o zaman başlangıç paragrafını en baştan yerleştiririm. Yeni bir paragraf başlatır dizinin her bir olayda (burada bir açıklama formunda) bir kırılma işareti eklemek istiyorum her durumda Sonra
(çünkü boşluk normalleşme
"\n\n"
olmalıdır, yanlış olabilir ve eğer olabilir Bu geçerli değil, bu çalışma şeffaf olması için boşluk boşluk normalleştirme yapmak gerekir. Bunlar takılı kırılma işaretleri sadece orada
/* @var $result DOMText[] */
$result = $xp->query('(.|./div)/text()', $anchor);
foreach ($result as $i => $node)
{
if ($node->parentNode->tagName == 'div')
{
$insertBreakMarkBefore($node, true);
}
while (FALSE !== $pos = strpos($node->data, $paragraphSequence))
{
$node = $node->splitText($pos + $paragraphSequenceLength);
$insertBreakMarkBefore($node);
}
}
HTML <p>
etiketiyle değiştirilmesi. Bir HTML ayrıştırıcısı bunları yeterli <p>...</p>
çiftine dönüştürür, böylece kendimi bu algoritmayı yazabilirim (bu ilginç olsa da). Bu temelde bir kez başka bir cevap özetlenen gibi çalışmak ama sadece linki artık bulmuyorum: DOM ağacının modifikasyonu sonra
- tekrar
<body>
innter HTML olsun.
- uygun
<p>...</p>
çiftiyle DOM yeniden oluşturmak için tekrar
- yük ayrıştırıcı içine HTML parçasını (bu görünür yapmak için de sınıf işaretlemek burada)
"<p>"
ile set izleri değiştirin.
- Şimdi en son olan
DOMDocument
ayrıştırıcısından HTML'yi yeniden edinin.
kodunda Bu aktarılan adımlar, (bir an için işlev tanımlarının bir atlama): Bu görüldüğü gibi
$needle = sprintf('%1$s<!--%2$s-->%1$s', $paragraphSequence, $paragraphComment);
$replace = sprintf("\n<p class=\"%s\">\n", $paragraphComment);
$html = strtr($innerHTML($anchor), array($needle . $needle => $replace, $needle => $replace));
echo "HTML afterwards:\n", $innerHTML($loadHTMLFragment($html));
, çift sekansları tek bir ile değiştirilir. Muhtemelen sonunda bir de silinmesi gerekiyor (eğer uygulamalısınız, ayrıca burada boşlukları da kesebilirsiniz).
nihai HTML çıktı: güzel çıktı biçimlendirme için
<div>
<p class="break">
This text should be wrapped in a p tag.
</p>
</div>
<p class="break">
This also should be wrapped.
</p>
<p class="break">
<b>And</b> this.</p>
Biraz daha post-prodüksiyon de yararlı olabilir. Aslında bence algoritmanın ayarlanmasına yardımcı olacağına inanıyorum (Full Demo - sadece görüyorum, boşluk boşluk normalizasyonu muhtemelen orada geçerli değil. Bu yüzden dikkatli kullanın).
Ayrıca 'div's dışındaki metin düğümlerini seçmek isterseniz, //ath '' ı XPath ifadenize koydunuz? [Bu keman] (http://codepad.org/hzOefCsH) istediğini yapıyormuş gibi görünüyor. – nwellnhof
Yukarıda kaydettiğim çözümle ilgili sorunun ne olduğunu söyleyebilir misiniz? Metni yeni satırlarla birden çok paragrafa dönüştürmek ister misiniz? – nwellnhof
@nwellnhof, çözümünüz gayet iyi - ama bu bir cevap değil, bu yüzden size hiçbir şey veremem. – Xeoncross