9

我正在尝试使用System.Xml.Linq来创建 XHTML 文档。因此,我的树中的绝大多数节点都应该使用这个命名空间:

http://www.w3.org/1999/xhtml

我可以XElement很容易地创建范围为这个命名空间的节点,使用一个XNamespace,像这样:

XNamespace xhtml = "http://www.w3.org/1999/xhtml";
// ...
new XElement(xhtml + "html", // ...

但是,我不想XNamespace在创建 HTML 节点的所有代码中都提供一个可用的,并且必须为我创建的每个XElement(和XAttribute)名称添加前缀。

XML 文本格式本身考虑了这一要求,并允许使用 reservedxmlns属性在由后代继承的祖先中设置默认命名空间。我想使用System.Xml.Linq.

这可能吗?

4

3 回答 3

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方法(此处未显示我的所有课程)。

于 2009-02-07T15:11:42.730 回答
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);
        }
    }
于 2010-05-28T14:03:48.073 回答
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 的缺点,但优点是命名空间 +“标记名”的转换只发生一次。我不确定这种转换是否会被优化。我确信 XNames 只被实例化一次:-

XNamepace n = "http://www.w3.org/1999/xhtml";
XNames x = n + "A";
XName y = n + "A";
Object.ReferenceEquals(x, y) //is true.
于 2009-01-25T18:02:19.343 回答