5

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

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

结果必须是:

  • 项目名称(服务器)
    • PropertyName(名称)、PropertyValue(MyServerName)
  • 项目名称(数据库)
    • PropertyName(名称)、PropertyValue(MyDatabaseName)
  • 项目名称(表)
    • PropertyName(名称)、PropertyValue(MyTableName)
    • 属性名(架构)、属性值(MySchemaName)

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

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

更新。

答案找到了,见下文。

4

4 回答 4

5

嗯,我做到了。:)

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

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

        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 的提示!

于 2012-08-21T07:50:51.923 回答
1

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

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

将导致“MyTableName”

于 2013-03-20T14:43:08.730 回答
0

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

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

剩下的唯一事情就是为它们中的每一个识别正确的数组索引

于 2012-08-21T06:57:25.553 回答
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)

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

于 2012-08-21T07:39:48.363 回答