هل من الممكن لإصلاح مشكلة في HtmlAgilityPack عندما يكون هناك علامة أتش تي أم أل ليست مغلقة؟

StackOverflow https://stackoverflow.com/questions/1928293

  •  20-09-2019
  •  | 
  •  

سؤال

وكذلك لدي المشكلة التالية.
تالف أتش تي أم أل لدي ولدي مشاكل مع اختيار العقد باستخدام أتش تي أم أل رشاقة حزمة عندما يكون هذا هو الحال.
رمز هو التالي:

string strHtml = @"
<html>
  <div>
    <p><strong>Elem_A</strong>String_A1_2 String_A1_2</p>
    <p><strong>Elem_B</strong>String_B1_2 String_B1_2</p>
  </div>
  <div>
    <p><strong>Elem_A</strong>String_A2_2 <String_A2_2> asdas</p>
    <p><strong>Elem_B</strong>String_B2_2 String_B2_2</p>
  </div>
</html>";
HtmlAgilityPack.HtmlDocument objHtmlDocument = new HtmlAgilityPack.HtmlDocument();
objHtmlDocument.LoadHtml(strHtml);
HtmlAgilityPack.HtmlNodeCollection colnodePs = objHtmlDocument.DocumentNode.SelectNodes("//p");
List<string> lststrText = new List<string>();
foreach (HtmlAgilityPack.HtmlNode nodeP in colnodePs)
{
  lststrText.Add(nodeP.InnerHtml);
}

والمشكلة هي أن يتم وضع String_A2_2 بين قوسين.
حتى htmlagility عوائد حزمة 5 سلاسل بدلا من 4 في lststrText.
لذلك ليس من الممكن السماح لعنصر حزمة htmlagility عودة 3 كما "<strong>Elem_A</strong>String_A2_2 <String_A2_2> asdas" منتديات أو ربما يمكنني القيام به بعض تجهيزها لإغلاق العنصر منتديات المحتوى الحالي من lststrText هو

lststrText[0] = "<strong>Elem_A</strong>String_A1_2 String_A1_2"  
lststrText[1] = "<strong>Elem_B</strong>String_B1_2 String_B1_2"  
lststrText[2] = ""  
lststrText[3] = ""  
lststrText[4] = "<strong>Elem_B</strong>String_B2_2 String_B2_2"
هل كانت مفيدة؟

المحلول

ومعظم موزعي أتش تي أم أل محاولة لبناء DOM العمل، وهذا يعني لا تقبل باتت العلامات. سيتم تحويلها، أو مغلقة في بعض الطريق.

إذا اختيار فقط العقد هو من أهمية بالنسبة لك، والسرعة وكميات هائلة من البيانات ليست قضية، هل يمكن أن الاستيلاء على كل ما تبذلونه من

العلامات مع تعبير عادي بدلا من ذلك:

Regex reMatchP = new Regex(@"<(p)>.*?</\1>");
foreach (Match m in reMatchP.Matches(strHtml))
{
   Console.WriteLine(m.Value);
}

وهذا التعبير العادي يفترض

علامات تتشكل بشكل جيد ومغلقة.

إذا كنت لتشغيل هذه التعبيرات المنتظمة الكثير في البرنامج يجب أن نعلن ذلك على النحو التالي:

static Regex reMatchP = new Regex(@"<(p)>.*?</\1>", RegexOptions.Compiled);

[تحرير: أجيليتي تغيير حزمة]

إذا كنت تريد استخدام HtmlAgility حزمة يمكنك تعديل الدالة PushNodeEnd في HtmlDocument.cs:

if (HtmlNode.IsCDataElement(CurrentNodeName()))
{
   _state = ParseState.PcData;
   return true;
}

// new code start
if ( !AllowedTags.Contains(_currentnode.Name) )
{
    close = true;
}
// new code end

وحيث AllowedTags ستكون قائمة كافة العلامات المعروفة: ب، ع، ر، العمر، شعبة، الخ

والإخراج هو ليس 100٪ ما تريد، ولكن ربما يكفي وثيقة؟

<strong>Elem_A</strong>String_A1_2 String_A1_2
<strong>Elem_B</strong>String_B1_2 String_B1_2
<strong>Elem_A</strong>String_A2_2 <ignorestring_a2_2></ignorestring_a2_2> asdas
<strong>Elem_B</strong>String_B2_2 String_B2_2

نصائح أخرى

هل يمكن استخدام TidyNet لتفعل قبل / تحليل نتائج التي يلمح إليها. يمكنك تحرير الإجابة على تفسير لماذا هذا لن تكون قابلة للتطبيق في الحالة الخاصة بك؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top