0

可以验证 xml 文件/字符串,但如果通过 XPath 或 linq to xml 查询则不会产生任何结果。不同之处在于: xmlns=""testNS"" xsi:... 在示例字符串中。没有这个 xmlns=... 它可以工作,没有它就不行(但它会验证)。

以下程序显示了我不明白的问题:(VS2012)

using System;
using System.Linq;
using System.Xml.Linq;

namespace XmlNamespaceTest
{
class Program
{
    static void Main(string[] args)
    {
        string xmlStringWithNs = GetStringWithNs();
        bool resultWithNs = Test(xmlStringWithNs);

        string xmlStringWithoutNs = GetStringWithoutNs();
        bool resultWithoutNs = Test(xmlStringWithoutNs);

        string xmlStringPlaying = GetModifiedNsForPlaying();
        bool resultPlaying = Test(xmlStringPlaying);

        Console.WriteLine("with ns: {0}", resultWithNs);
        Console.WriteLine("without ns: {0}", resultWithoutNs); 
        Console.WriteLine("playing: {0}", resultPlaying);

        Console.Read();
    }

    private static bool Test(string xmlString)
    {
        XNamespace ns = "http://www.w3.org/2001/XMLSchema-instance";

        var root = XElement.Parse(xmlString);
        var es = root.Descendants("Event")
            .Where(e => e.Attribute("serviceId").Value == "SERVICEID");
        var list = es.ToList();

        return list.Count > 0;
    }

    private static string GetModifiedNsForPlaying()
    {
        return
            @"<?xml version=""1.0"" encoding=""UTF-8""?>
            <dataset xmlns=""testNS"" xsi:schemaLocation=""testNS Test.xsd"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
                <eventCommands>
                    <DEFINE><Event eventId=""EVENTID"" serviceId=""SERVICEID"" /></DEFINE>
                </eventCommands>
            </dataset>";
    }

    private static string GetModifiedNs()
    {
        return
            @"<?xml version=""1.0"" encoding=""UTF-8""?>
            <dataset xmlns=""testNS"" xsi:schemaLocation=""testNS Test.xsd"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
                <eventCommands>
                    <DEFINE><Event eventId=""EVENTID"" serviceId=""SERVICEID"" /></DEFINE>
                </eventCommands>
            </dataset>";
    }
    /// <summary>
    /// Does not contain: xmlns=""testNS""
    /// Successfull!
    /// </summary>
    /// <returns>true if found, false else</returns>
    private static string GetStringWithoutNs()
    {
        return
            @"<?xml version=""1.0"" encoding=""UTF-8""?>
            <dataset xsi:schemaLocation=""Test.xsd"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
                <eventCommands>
                    <DEFINE><Event eventId=""EVENTID"" serviceId=""SERVICEID"" /></DEFINE>
                </eventCommands>
            </dataset>";
    }

    /// <summary>
    /// GetStringWithNs
    /// 
    /// Does contain: xmlns=""testNS""
    /// NOT Successfull! 
    /// Validation against an xsd succeeds.
    /// </summary>
    /// <returns>true if found, false else</returns>
    private static string GetStringWithNs()
    {
        return
            @"<?xml version=""1.0"" encoding=""UTF-8""?>
            <dataset xmlns=""testNS"" xsi:schemaLocation=""Test.xsd"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
                <eventCommands>
                    <DEFINE><Event eventId=""EVENTID"" serviceId=""SERVICEID"" /></DEFINE>
                </eventCommands>
            </dataset>";
    }
}
}
4

1 回答 1

0

如果要使用 XPath 或 LINQ to XML 查询具有命名空间的元素,则必须指定该命名空间。例如:

XNamespace ns = "testNS";       
var root = XElement.Parse(xmlString);
return root.Descendants(ns + "Event")
           .Where(e => (string) e.Attribute("serviceId") == "SERVICEID")
           .Any();

(我也使查询更清晰,IMO - 我倾向于对 LINQ to XML 使用强制转换而不是使用Value属性,我建议您使用Any而不是计算结果。)

于 2013-09-20T12:14:21.637 回答