如何从SMO解析这个类似路径的字符串?

时间:2012-08-21 06:46:02

标签: c#

我想知道,有没有任何标准的方法来解析这种类似路径的字符串:

Server[@Name='MyServerName']/Database[@Name='MyDatabaseName']/Table[@Name='MyTableName' and @Schema='MySchemaName']

结果必须是:

  • ItemName(服务器)
    • PropertyName(Name),PropertyValue(MyServerName)
  • ItemName(数据库)
    • PropertyName(Name),PropertyValue(MyDatabaseName)
  • ItemName(表格)
    • PropertyName(Name),PropertyValue(MyTableName)
    • PropertyName(架构),PropertyValue(MySchemaName)

这里最明显的是制作一个正则表达式(当然还有String.Split),但是可能有更好的标准方法吗?

有关信息:字符串来自SMO的Urn.Value

更新

找到答案,见下文。

4 个答案:

答案 0 :(得分:5)

嗯,我做到了。 :)

答案很简单。有Urn.XPathExpression财产。但它的返回值类型是Microsoft.SqlServer.Management.Sdk.Sfc.XPathExpression,而不是System.Xml.XPath.XPathExpression(这让我很困惑)。

来自SMO的XPathExpression具有解析自身的所有必要功能:

        var urn = new Urn("Server[@Name='MyServerName']/Database[@Name='MyDatabaseName']/Table[@Name='MyTableName' and @Schema='MySchemaName']");

        for (var i = 0; i < urn.XPathExpression.Length; i++)
        {
            Console.WriteLine("ItemName ({0})", urn.XPathExpression[i].Name);

            foreach (DictionaryEntry item in urn.XPathExpression[i].FixedProperties)
            {
                Console.WriteLine("\tPropertyName ({0}), PropertyValue ({1})", item.Key, item.Value);
            }
        }

生成此输出:

ItemName (Server)
        PropertyName (Name), PropertyValue ('MyServerName')
ItemName (Database)
        PropertyName (Name), PropertyValue ('MyDatabaseName')
ItemName (Table)
        PropertyName (Name), PropertyValue ('MyTableName')
        PropertyName (Schema), PropertyValue ('MySchemaName')

Christian.K,感谢有关XPath的暗示!

答案 1 :(得分:0)

没有要测试的代码应用,但有类似

的内容

var resultArr=str.Split(new char[]{'/', '[',']','@', '='});应该创建一个你想要的工件数组。

唯一剩下的就是为每个人识别正确的数组索引

答案 2 :(得分:0)

我相信,唯一的标准方法是使用正则表达式与模式匹配

以下代码段会有所帮助 -

    string input = @"Server[@Name='MyServerName']/Database[@Name='MyDatabaseName']/Table[@Name='MyTableName' and @Schema='MySchemaName']";
    string elementPattern = @"(?<ItemName>\w+)\[@(?<PropertyName>\w+)='(?<PropertyValue>\w+)'( and @(?<PropertyName>\w+)='(?<PropertyValue>\w+)')*\]";

    Regex elementRegex = new Regex(elementPattern, RegexOptions.Compiled);

    string[] elements = input.Split('/');

    foreach (string element in elements)
    {
        Match m = elementRegex.Match(element);

        if (m.Success)
        {
            Console.WriteLine("ItemName ({0})", m.Groups["ItemName"]);

            foreach (Capture capture in m.Groups["PropertyName"].Captures)
            {
                Console.WriteLine("PropertyName ({0})", capture.Value);
            }

            foreach (Capture capture in m.Groups["PropertyValue"].Captures)
            {
                Console.WriteLine("PropertyValue ({0})", capture.Value);
            }
        }
    }

    Console.ReadKey();

输出: -

ItemName (Server)
PropertyName (Name)
PropertyValue (MyServerName)
ItemName (Database)
PropertyName (Name)
PropertyValue (MyDatabaseName)
ItemName (Table)
PropertyName (Name)
PropertyName (Schema)
PropertyValue (MyTableName)
PropertyValue (MySchemaName)

注意:请根据您的要求进行更改。

答案 3 :(得分:0)

也许有点晚了,但我正在寻找相同的答案,然后我自己偶然发现了这个问题。 Urn有几个Get函数。

 var urn = new Urn("Server[@Name='MyServerName']/Database[@Name='MyDatabaseName']/Table[@Name='MyTableName' and @Schema='MySchemaName']");
    Console.WriteLine(urn.GetNameForType("Table"));

会导致“MyTableName”