0
我有DataContract
類MyDataContract
。我將它序列化爲一個XML文件。後來,在我的應用程序的一個完全不同的「地方」,我正在加載這個文件。在那裏,我想驗證只加載,如果文件的內容符合特殊條件。比方說,假設一個人可以擁有一輛車,我將一個人和該協會存儲在該人的車輛上。 :-)XPath匹配XML序列化DataContract類
這裏DataContract
類:
namespace Test.DataContracts
{
[DataContract]
public class MyDataContract
{
[DataMember]
public string Identifier { get; set; }
[DataMember]
public Common.Person Person { get; set; }
[DataMember]
public Common.Vehicle Vehicle { get; set; }
}
}
namespace Test.DataContracts.Common
{
[DataContract]
public class Person
{
[DataMember]
public Global.Gender Gender { get; set; }
[DataMember]
public string Info { get; set; }
[DataMember]
public string Name { get; set; }
}
[DataContract]
public class Vehicle
{
[DataMember]
public string Info { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Vendor { get; set; }
}
}
namespace Test.DataContracts.Global
{
[DataContract]
public class Gender
{
[DataMember]
public int Type { get; set; }
[DataMember]
public string Name { get; set; }
}
}
結果在下面的序列化的XML:
<?xml version="1.0" encoding="utf-8"?>
<MyDataContract xmlns="http://schemas.datacontract.org/2004/07/Test.DataContracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Identifier>123456789</Identifier>
<Person xmlns:a="http://schemas.datacontract.org/2004/07/Test.DataContracts.Common">
<a:Gender xmlns:b="http://schemas.datacontract.org/2004/07/Test.DataContracts.Global">
<b:Name>Female</b:Name>
<b:Type>0</b:Type>
</a:Gender>
<a:Info>She is a beautiful lady.</a:Info>
<a:Name>Jane Doe</a:Name>
</Person>
<Vehicle xmlns:a="http://schemas.datacontract.org/2004/07/Test.DataContracts.Common">
<a:Info>A super great car.</a:Info>
<a:Name>Mustang 1983 Turbo GT</a:Name>
<a:Vendor>Ford</a:Vendor>
</Vehicle>
</MyDataContract>
現在我想篩選出唯一的女性(Type = 0)
人認爲擁有任何福特(Vendor = Ford)
車輛。我嘗試了以下方法,但總是會在false
的比賽中結果。
string path = @"c:\janedoe.xml";
var xmlDoc = new XmlDocument();
xmlDoc.Load(path);
XmlNodeList xNodes = xmlDoc.SelectNodes(@"//namespace::*[not(. = ../../namespace::*)]");
var xNamespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
foreach (XmlNode node in xNodes)
{
if (!string.IsNullOrWhiteSpace(xNamespaceManager.LookupNamespace(node.LocalName))) continue;
xNamespaceManager.AddNamespace(node.LocalName, node.Value);
}
using (var fs = new FileStream(path, FileMode.Open))
{
var xDocument = new XPathDocument(fs);
var xNavigator = xDocument.CreateNavigator();
XPathExpression exp1 = xNavigator.Compile(string.Format("MyDataContract/Person/Gender/Type/descendant::*[contains(text(), '{0}')]", "0"));
exp1.SetContext(xNamespaceManager);
XPathExpression exp2 = xNavigator.Compile(string.Format("MyDataContract/Vehicle/Vendor/descendant::*[contains(text(), '{0}')]", "Ford"));
exp2.SetContext(xNamespaceManager);
if (xNavigator.Matches(exp1) && xNavigator.Matches(exp2))
{
Console.WriteLine("File '{0}' indicates a female person that owns a vehicle of Ford.", path);
}
else
{
Console.WriteLine("File '{0}' has no matches (female and Ford).", path);
}
}
任何人都可以幫忙嗎?
UPDATE 1 - 我已經使用XmlNamespaceManager更改了代碼。但執行xNavigator.Matches(exp1)
時仍然會導致false
。
是否有一個原因,你必須使用XPath進行搜索?你可以反序列化數據並使用Linq來檢查條件。 – Ryan
您必須考慮名稱空間。搜索namespacemanager以及如何使用這些。 – rene
Ryan:是的我需要XPath,因爲我的程序是第三方,實際上並不知道對象(這只是一個例子)。 雷內:謝謝你的提示,我會就此進行調查! – moik