2012-08-21 2 views
4

HtmlAgilityPack을 사용하고 있습니다. 모든 P 태그를 검색하고 P 태그 내의 스타일에 "margin-top : 0px"를 추가합니다.HtmlAgilityPack을 사용하여 Html에 스타일 속성을 추가하는 더 나은 방법

당신이 볼 수 있듯이 그것은 margin-top 속성의 "brute forcing"입니다. HtmlAgilityPack을 사용하여이 작업을 수행하는 더 좋은 방법이 있어야하지만 찾을 수 없으며 HtmlAgilityPack 설명서가 존재하지 않습니다.

아무도 더 좋은 방법을 알고 계십니까?

 HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(@style,'margin-top'))]"); 
     if (pTagNodes != null && pTagNodes.Any()) 
     { 
      foreach (HtmlNode pTagNode in pTagNodes) 
      { 
       if (pTagNode.Attributes.Contains("style")) 
       { 
        string styles = pTagNode.Attributes["style"].Value; 
        pTagNode.SetAttributeValue("style", styles + "; margin-top: 0px"); 
       } 
       else 
       { 
        pTagNode.Attributes.Add("style", "margin-top: 0px"); 
       } 
      } 
     } 



UPDATE : 나는 알렉스의 제안에 따라 코드를 수정했습니다. 더 "DOM"방식으로 스타일 속성을 처리 할 HtmlAgilityPack에 내장 된 기능이 있는지 알고 싶습니다.

 const string margin = "; margin-top: 0px"; 

     HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(@style,'margin-top'))]"); 
     if (pTagNodes != null && pTagNodes.Any()) 
     { 
      foreach (var pTagNode in pTagNodes) 
      { 
       string styles = pTagNode.GetAttributeValue("style", ""); 
       pTagNode.SetAttributeValue("style", styles + margin); 
      } 
     } 

답변

4

당신은 HtmlNode.GetAttributeValue 방법을 사용하고 "여백 정상" 마법 문자열 상수하여 코드를 조금 단순화 수 : 매우 크게 개선

const string margin = "margin-top: 0"; 
foreach (var pTagNode in pTagNodes) 
{ 
    var styles = pTagNode.GetAttributeValue("style", null); 
    var separator = (styles == null ? null : "; "); 
    pTagNode.SetAttributeValue("style", styles + separator + margin); 
} 

안하지만 코드가 더 간단합니다.

+0

감사합니다. Alex, 나는 이러한 변화가 마음에 들며 그것을 만들 예정입니다. 나는 당신을 upvoted했지만 질문을 지금 열려있는 유지하고 싶습니다. 누군가가 HtmlAgilityPack에서 스타일 속성을 구문 분석하고 일부 콜렉션 유형 구조를 통해 여백을 추가 할 수있는 기능을 알고 있기를 바란다. 나는 보았지만 하나를 찾을 수 없었지만 그것이 그것이 없다는 것을 의미하지는 않습니다. –

+0

@Gene S, AgilityPack이'style' 속성의 내용을 파싱 할 수 있을지 의심 스럽습니다. 그러나'string.Split' 메쏘드를 사용하여 속성 값을 세미콜론 (';')으로 나눌 수 있고, 그 값을 처리하고,'string.Join'을 사용하여 값을 * pack * 할 수 있습니다. – Alex

+0

나는 그것에 대해 생각했다. 어쩌면 내가 AgilityPack으로 구워 지도록 약간의 확장 메소드를 생성 할 것입니다. 귀하의 의견에 감사드립니다. –

3

우선 무엇을 요구 했습니까? 알렉스 솔루션은 항상 현재의 문제에 대해 잘 작동해야합니다. 문제가 더 복잡하고 복잡해지면 항상 "간단합니다".

어쨌든 AgilityPack에는 그러한 종류의 기능이 없지만 .Net Framework에는 있습니다. 이것은 넷용입니다. 넷용, 이전 버전을 사용한다면 조금 다를 수 있습니다. 먼저 System.Web.dll은 CssStyleCollection Class과 함께 제공됩니다.이 클래스는 이미 인라인 CSS를 파싱 할 수있는 모든 기능을 갖추고 있습니다. 단 하나의 캐치가 있습니다. 내부 생성자이므로 솔루션이 약간 "해킹"됩니다. 먼저 클래스의 인스턴스를 생성하기 위해 필요한 것은 모두 약간의 반성입니다. 코드는 이미 수행되었습니다 here. 이 기능은 현재 작동하지만 향후 버전의 .Net에서 중단 될 수 있음을 명심하십시오. 당신이 어떤 이유로 경우 System.Web 참조를 추가 할 수 없습니다 (당신은 닷넷 4 클라이언트 프로파일을 사용하는 경우 경우 것) 가능성에 항상이 있다면 모든 것을이 남아 는

CssStyleCollection css = CssStyleTools.Create(); 
css.Value = "border-top:1px dotted #BBB;margin-top: 0px;font-size:12px"; 
Console.WriteLine(css["margin-top"]); //prints "0px" 

정말 간단합니다 반사경을 사용하십시오.

개인적으로 저는 Alex의 해결책을 생각해 보았습니다.하지만 결정은 여러분에게 달려 있습니다. :)

+0

내 직감은 알렉 스의 해결책과 함께 나에게 알려주지 만 귀하의 의견에 감사드립니다.Agility Pack에서 뭔가를 간과하지 않았다는 것을 알고 기쁩니다. –

관련 문제