我正在尝试使用System.Xml.Linq
来创建XHTML文档。因此,我树中的绝大多数节点都应该使用这个命名空间:
http://www.w3.org/1999/xhtml
我可以使用XElement
轻松地创建范围为此命名空间的XNamespace
个节点,如下所示:
XNamespace xhtml = "http://www.w3.org/1999/xhtml";
// ...
new XElement(xhtml + "html", // ...
但是,我不希望在创建HTML节点的所有代码中都提供XNamespace
,并且必须为每个XElement
(和XAttribute
)名称添加前缀我相应地创作。
XML文本格式本身考虑了这一要求,并允许使用保留的xmlns
属性在后代继承的祖先中设置默认命名空间。我想使用System.Xml.Linq
做类似的事情。
这可能吗?
答案 0 :(得分:5)
我决定使用名为XHtml
的静态类,如下所示:
public static class XHtml
{
static XHtml()
{
Namespace = "http://www.w3.org/1999/xhtml";
}
public static XNamespace Namespace { get; private set; }
public static XElement Element(string name)
{
return new XElement(Namespace + name);
}
public static XElement Element(string name, params object[] content)
{
return new XElement(Namespace + name, content);
}
public static XElement Element(string name, object content)
{
return new XElement(Namespace + name, content);
}
public static XAttribute Attribute(string name, object value)
{
return new XAttribute(/* Namespace + */ name, value);
}
public static XText Text(string text)
{
return new XText(text);
}
public static XElement A(string url, params object[] content)
{
XElement result = Element("a", content);
result.Add(Attribute("href", url));
return result;
}
}
这似乎是最干净的做事方式,特别是当我可以添加便利例程时,例如XHtml.A
方法(这里没有显示我的所有类)。
答案 1 :(得分:3)
我采用了递归重写路径。你真的不需要'重建'树。您只需换出节点名称(XName
)。
private static void ApplyNamespace(XElement parent, XNamespace nameSpace)
{
if(DetermineIfNameSpaceShouldBeApplied(parent, nameSpace))
{
parent.Name = nameSpace + parent.Name.LocalName;
}
foreach (XElement child in parent.Elements())
{
ApplyNamespace(child, nameSpace);
}
}
答案 2 :(得分:1)
问题是用于创建XElement的XName需要指定正确的命名空间。我想要做的是创建一个这样的静态类: -
public static class XHtml
{
public static readonly XNamespace Namespace = "http://www.w3.org/1999/xhtml";
public static XName Html { get { return Namespace + "html"; } }
public static XName Body { get { return Namespace + "body"; } }
//.. other element types
}
现在你可以建立一个像这样的xhtml文档: -
XDocument doc = new XDocument(
new XElement(XHtml.Html,
new XElement(XHtml.Body)
)
);
该静态类的另一种方法是: -
static class XHtml
{
public static readonly XNamespace Namespace = "http://www.w3.org/1999/xhtml";
public static readonly XName Html = Namespace + "html";
public static readonly XName Body = Namespace + "body";
}
无论你是否使用它们,这都有实例化所有可能的XName的缺点,但好处是Namespace的转换+“tagname”只发生一次。我不确定这种转换是否会被优化。我确信XNames只实例一次: -
XNamepace n = "http://www.w3.org/1999/xhtml";
XNames x = n + "A";
XName y = n + "A";
Object.ReferenceEquals(x, y) //is true.