2011-10-31 40 views
1

我以cgicc開頭,讓我保持代碼簡短和乾淨。但現在我正在掙扎。我想有這樣的事情:cgicc:多層次的相同元素

<ul> 
    <li> 
    <a href="#" ><span>Main 1</span></a> 
    <ul> 
     <li><a href="ref1-1" ><span>Sub 1</span></a></li> 
     <li><a href="ref1-2" ><span>Sub 2</span></a></li> 
     <li><a href="ref1-3" ><span>Sub 3</span></a></li> 
    </ul> 
    </li> 
    <li> 
    <a href="#" ><span>Main 2</span></a> 
    <ul> 
     <li><a href="ref2-1" ><span>Sub 1</span></a></li> 
     <li><a href="ref2-2" ><span>Sub 2</span></a></li> 
     <li><a href="ref2-3" ><span>Sub 3</span></a></li> 
    </ul> 
    </li> 
</ul> 

內部塊是非常大的,所以我不想在呼叫組合。我喜歡這首atttempt(我希望我編寫得很好):

cout << ul() << endl; 
    cout << li() << endl; 
    cout << a("Main 1").set("href", "#") << endl; 
    cout << ul() << endl; // <-- must fail here! 
     cout << li(a("Sub 1").set("href", "ref1-1")) << endl; 
     cout << li(a("Sub 2").set("href", "ref1-2")) << endl; 
     cout << li(a("Sub 3").set("href", "ref1-3")) << endl; 
    cout << ul() << endl; 
    cout << li() << endl; 
    cout << li() << endl; 
    cout << a("Main 2").set("href", "#") << endl; 
    cout << ul() << endl; 
     cout << li(a("Sub 1").set("href", "ref2-1")) << endl; 
     cout << li(a("Sub 2").set("href", "ref2-2")) << endl; 
     cout << li(a("Sub 3").set("href", "ref2-3")) << endl; 
    cout << ul() << endl; 
    cout << li() << endl; 
cout << ul() << endl; 

問題是對於像< ul>和< LI>等,所以元素的布爾狀態,是有一個最佳實踐和智能解決方案來處理這個? - 安迪

編輯:我的新的解決方案:附加要素類的「簡單」:

#include <cgicc/HTMLElement.h> 
#include <cgicc/HTMLAttributeList.h> 

template<class Tag> 
class HTMLSimpleElement : public cgicc::HTMLElement 
{ 
public: 
    HTMLSimpleElement() : HTMLElement(0, 0, 0, EElementType(-1)) 
    {} 

    HTMLSimpleElement(const cgicc::HTMLAttributeList& attributes) : HTMLElement(&attributes, 0, 0, EElementType(-1)) 
    {} 

    virtual ~HTMLSimpleElement() {} 

    virtual inline HTMLElement* clone() const 
    { return new HTMLSimpleElement<Tag>(*this); } 

    virtual inline const char* getName() const 
    { return Tag::getName(); } 

    virtual void render(std::ostream& out) const 
    { 
    const cgicc::HTMLAttributeList* attributes = getAttributes(); 

    out << '<' << getName(); 

    if (attributes != NULL) 
    { 
     out << ' '; 
     attributes->render(out); 
    } 

    out << ">"; 
    } 
}; 

#define TAG(name, tag) \ 
class name##Tag \ 
{ public: inline static const char* getName() { return tag; } } 

#define SIMPLE_ELEMENT(name, tag) \ 
TAG(name, tag); typedef HTMLSimpleElement<name##Tag> name 

SIMPLE_ELEMENT (divB, "div"); 
SIMPLE_ELEMENT (divE, "/div"); 

// and so on... 

這樣我可以使用成員函數,並已超過BEGIN和END標籤完全控制。任何人,更聰明的解決方案?

+0

我可以提供一個解決方法:定義我自己的BOOLEAN_ELEMENT,如:BOOLEAN_ELEMENT(ul1,「ul」); BOOLEAN_ELEMENT(ul2,「ul」);等等。然後我使用關聯關卡上的每個具體編號。任何其他想法? – Andi

回答

2

這是一種古老的,你可能已經找到了你的答案,但如果他們有同樣的問題,它可以幫助別人。

您的第二個代碼塊不正確。當你用cgicc標記一個標籤時,它輸出整個標籤,包括包含的孩子。沒有包容的孩子,州政府就會記憶下來,並與每個建築物交換。這意味着要堆疊它們,您應該使用您組裝爲樹的對象。 對於一個簡單的例子,藉此縮短所需的輸出:

<ul> 
    <li> 
    <a href="#" ><span>Main 1</span></a> 
    <ul> 
     <li><a href="ref1-1" ><span>Sub 1</span></a></li> 
     <li><a href="ref1-2" ><span>Sub 2</span></a></li> 
     <li><a href="ref1-3" ><span>Sub 3</span></a></li> 
    </ul> 
    </li> 
</ul> 

如果您嘗試cgicc代碼,例如:

cout << ul() << endl; 
    cout << li() << endl; 
    cout << a("Main 1").set("href", "#") << endl; 
    cout << ul() << endl; // <-- must fail here! 
     cout << li(a("Sub 1").set("href", "ref1-1")) << endl; 
     cout << li(a("Sub 2").set("href", "ref1-2")) << endl; 
     cout << li(a("Sub 3").set("href", "ref1-3")) << endl; 
    cout << ul() << endl; 
    cout << li() << endl; 
cout << ul() << endl; 

你會得到這個爛攤子,這是不正確的html:

<ul> 
<li> 
<a href="#" >Main 1</a> 
</ul> 
<li><a href="ref1-1" >Sub 1</a></li> 
<li><a href="ref1-2" >Sub 2</a></li> 
<li><a href="ref1-3" >Sub 3</a></li> 
<ul> 
</li> 
</ul> 

您應該更加面向對象地處理這個問題,跟蹤您用於構建頁面的對象,就像這樣(指針會跟蹤最新的adde d孩子,並且會避免製造不必要的副本;沒有指針,你需要確保以正確的順序添加標籤):

ul* outerList = new ul(); 
li* outerItem = new li(); 
ul* innerList = new ul(); 

outerList->add(outerItem); 
outerItem->add(a(span("Main 1")).set("href", "#")); 
outerItem->add(innerList); 
innerList->add(li(a(span("Sub 1")).set("href", "ref1-1"))); 
innerList->add(li(a(span("Sub 2")).set("href", "ref1-2"))); 
innerList->add(li(a(span("Sub 3")).set("href", "ref1-3"))); 

cout << *outerList << endl; 

您也可以建立他們在飛行中,使用構造和添加和設置方法:

cout << ul(li().add(a(span("Main 1")).set("href", "#")).add(ul().add(li(a(span("Sub 1")).set("href", "ref1-1"))).add(li(a(span("Sub 2")).set("href", "ref1-2"))).add(li(a(span("Sub 3")).set("href", "ref1-3"))))) << endl; 

這是可以說不太清楚,難以遵循,難以調試,並且容易犯錯;你可以通過一些換行符和縮進來緩解它,但我不知道這會有多大幫助。

將HTML視爲層次結構。我總是有更好的時間簡單地使用XHTML和libxml。

+0

感謝您指出樹的行爲。事實上,我沒有意識到這種可能性。我不確定是否將我的代碼重構爲這種從內到外的定義會更具可讀性,但是這對於這個庫來說是正確的方式。最後一個使用怪物線的例子最好不要推薦;-) – Andi

相關問題