我从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>
内部块非常大,因此我不想组合这些调用。我这样的第一个尝试(我希望我编码好):
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;
问题是像&lt;元素这样的元素的布尔状态。 ul&gt;和&lt; 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 :(得分: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>
您可能应该以更加面向对象的方式处理此问题,跟踪用于构建页面的对象,如此(指针将跟踪新添加的子项,并且将避免制作不必要的副本;没有指针,你需要确保以正确的顺序添加标签):
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时度过更好的时光。