使用XElement创建带前缀的XML元素

时间:2012-10-22 13:48:08

标签: c# xelement prefix

我有一个应用程序,它使用包含多个WPF自定义组件的画布。我想将这些组件导出到XAML文件中,以便它可以被另一个应用程序获取,但为了做到这一点,我需要为导出的组件添加前缀限定符。例如,如果我要导出一个FrequencyButtonA组件,我需要输出类似

的内容
<PanelControls:FrequencyButtonA Frequency="113.123" Width="250"/>

我尝试了以下内容,但由于使用了':'字符,我收到了异常:

return new XElement("PanelControls:" + "FrequencyButtonA");

有什么想法吗?我在SO中发现了一些其他问题,这些问题似乎与我遇到的问题类似(例如this link),但不是完全相同的情况。

提前致谢!

编辑 - 更多背景信息:这是我需要生成的完整输出的示例:

<Border x:Name="CommsPanelBorder"
    Style="{DynamicResource BorderTemplate}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:PanelControls="clr-namespace:CommsPanelControlsLib.View;assembly=CommsPanelControlsLib"
    VerticalAlignment="Top">
        <PanelControls:FrequencyButtonB Frequency="113.123" Width="250"/>
        <PanelControls:FrequencyButtonA Frequency="102.3" Width="150"/>

我忘了在原帖中提到根节点(Border)是在方法中创建的。然后,该方法遍历放置在画布中的所有元素,并在所述元素上调用一个方法,该方法返回一个XElement,稍后将其添加到根节点。因此,我需要让XElements能够创建自己。该方法的代码如下:

XNamespace aw = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
        XNamespace ns = "PanelControls";
        var root = new XElement(aw + "Border",
            new XAttribute("Style", "{DynamicResource BorderTemplate}"),
            new XAttribute("Name", "CommsPanelBorder"),
            new XAttribute(XNamespace.Xmlns + "x", "http://schemas.microsoft.com/winfx/2006/xaml"),
            new XAttribute(XNamespace.Xmlns + "PanelControls", "clr-namespace:CommsPanelControlsLib.View;assembly=CommsPanelControlsLib"),
            new XAttribute("VerticalAlignment", "Top")
        );

        IEnumerable<CommsPanelControl> commsPanelControls = editCanvas.Children.OfType<CommsPanelControl>();

        foreach (var commsPanelControl in commsPanelControls)
        {
            XElement xElement = commsPanelControl.AddXElement(root, ns);
            root.Add(xElement);
        }

编辑2.添加了一些代码,以便Reinder可以看到我当前的方法:

XNamespace aw = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
        XNamespace ns = "PanelControls";
        var root = new XElement(aw + "Border",
            new XAttribute("Style", "{DynamicResource BorderTemplate}"),
            new XAttribute("Name", "CommsPanelBorder"),
            new XAttribute(XNamespace.Xmlns + "x", "http://schemas.microsoft.com/winfx/2006/xaml"),
            new XAttribute(XNamespace.Xmlns + "PanelControls", "clr-namespace:CommsPanelControlsLib.View;assembly=CommsPanelControlsLib"),
            new XAttribute("VerticalAlignment", "Top")
        );

        XElement xElement = new XElement(ns + "FrequencyButtonA",
            new XAttribute("Frequency", "113.123"),
            new XAttribute("Width", "250"));
        root.Add(xElement);

编辑3.作为参考,这是我的问题的可能解决方案。感谢Reiner的输入!

XNamespace aw = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
        XNamespace ns = "clr-namespace:CommsPanelControlsLib.View;assembly=CommsPanelControlsLib";
        var root = new XElement(aw + "Border",
            new XAttribute("Style", "{DynamicResource BorderTemplate}"),
            new XAttribute("Name", "CommsPanelBorder"),
            new XAttribute(XNamespace.Xmlns + "x", "http://schemas.microsoft.com/winfx/2006/xaml"),
            new XAttribute(XNamespace.Xmlns + "PanelControls", "clr-namespace:CommsPanelControlsLib.View;assembly=CommsPanelControlsLib"),
            new XAttribute("VerticalAlignment", "Top")
        );

        XElement xElement = new XElement(ns + "FrequencyButtonA",
            new XAttribute("Frequency", "113.123"),
            new XAttribute("Width", "250"));
        root.Add(xElement);

2 个答案:

答案 0 :(得分:4)

PanelControls这样的前缀只有在声明与之相关的命名空间时才有意义。

您需要在节点本身或例如根目录中指定它。

// create the root element, with the 'PanelControls' namespace
XNamespace nSpace = "PanelControls";
XElement element = new XElement("root",
          new XAttribute(XNamespace.Xmlns + "PanelControls", nSpace));

element.Add(addXElement("FrequencyButtonA", nSpace ));

...

private static XElement addXElement(string n, XNamespace ns)
{
    return new XElement(ns + n,
        new XAttribute("Frequency", 113.123),
        new XAttribute("Width", 250));
}

方法'addXElement()'将在命名空间ns中创建新的XElement,所以你最终得到这个:

<?xml version="1.0"?>
<root xmlns:PanelControls="PanelControls">
    <PanelControls:FrequencyButtonA Width="250" Frequency="113.123"/>
</root>

答案 1 :(得分:1)

using System;
using System.Xml.Linq;


class Program
{
    static void Main(string[] args)
    {

        XNamespace @namespace = "PanelControls";
        XElement element = new XElement("root",
            new XAttribute(XNamespace.Xmlns + "PanelControls", @namespace),
            new XElement(@namespace + "FrequencyButtonA",
                new XAttribute("Frequency", 113.123),
                new XAttribute("Width", 250)));
        Console.WriteLine(element);
    }
}