商业应用程序使用XML来保存它使用的变量列表。我无法控制XML的格式。我可以使用任何版本的.Net
。
尝试编写更简单的代码,将UserVar
节点分配给我创建的对象。现在我找到UserVars部分的节点,其中包含所有单个UserVars
,遍历每个UserVar
寻找元素“Name”,然后查看它是否与我想要的变量名匹配。< / p>
例如,我希望变量“已更改”我将获得一个AcmeVar
对象(我的创建),其中属性Name
和Width
设置为“已更改”和1.但是我必须手动迭代代码。
好像我正在努力做到这一点。理想情况下,我很乐意使用Linq返回具有匹配元素Name的UserVar
节点。 Stackoverflow上的类似问题不遵循类似的模式,或者至少不是我能看到的。并非所有变量都使用所有元素类型。
示例:XML
<?xml version="1.0" encoding="UTF-8"?>
<Application>
<Vars>
<UserVars>
<UserVar>
<Name>"Quantity"</Name>
<Width>4</Width>
<VarValue>"1"</VarValue>
</UserVar>
<UserVar>
<Name>"Printers"</Name>
<Width>255</Width>
</UserVar>
<UserVar>
<Name>"Changed"</Name>
<Width>1</Width>
</UserVar>
<UserVar>
<Name>"Weight"</Name>
<VarValue>"450.1"</VarValue>
</UserVar>
</UserVars>
</Vars>
</Application>
当前代码:
public static bool GetVariable(string xmlDocNm, string varName, out AcmeVariable acmeVar)
{
// Returns true if found without error
bool result = false;
acmeVar = new AcmeVariable ();
try {
XPathDocument doc = new XPathDocument(xmlDocNm);
XPathNavigator nav = doc.CreateNavigator();
// Compile a standard XPath expression
XPathExpression expr;
expr = nav.Compile(AcmeConst.XPathInternalVariable);
XPathNodeIterator iterator = nav.Select(expr);
// Iterate on the node set
try {
bool variableFound;
bool skipNode;
char[] CharsToTrim = { '\"' }; //
while (iterator.MoveNext()) {
variableFound = false;
skipNode = false;
XPathNavigator nav2 = iterator.Current.Clone();
if (nav2.MoveToFirstChild()) {
// nav2 points to the first element in an UserVar Node
acmeVar = new AcmeVariable (); //Start with a fresh Acme Variable
if (nav2.LocalName == AcmeConst.AttrName) {
variableFound = true;
skipNode = nav2.Value.Trim(CharsToTrim) != varName;
}
if (!skipNode) {
AssignXMLNavNodetoAcmeVar(nav2, acmeVar);
while (nav2.MoveToNext() && !skipNode) {
if (nav2.LocalName == AcmeConst.AttrName) {
variableFound = true;
skipNode = nav2.Value.Trim(CharsToTrim) != varName;
}
AssignXMLNavNodetoAcmeVar(nav2, acmeVar);
}
}
}
if (variableFound && !skipNode) {
result = true;
break; //We have found the variable and collected all elements
}
else {
acmeVar = null;
}
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
acmeVar = null;
result = false;
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
acmeVar = null;
result = false;
}
return result;
}
答案 0 :(得分:3)
试试这个:
var queryValue = "Quantity";
var xDoc = XDocument.Load(@"UserVars.xml");//This is your xml path value
var userVar = xDoc.Descendents("UserVar").Where(x => x.Element("Name").Value == queryValue )
.FirstOrDefault();
var name = userVar.Element("Name").Value ?? string.Empty;
var width = userVar.Element("Width").Value ?? string.Empty;
var varValue = userVar.Element("VarValue").Value ?? string.Empty;
我只想对您的XML发表评论,尤其是在<Name>"Quantity"</Name>
""
元素值的部分
但是如果你没有与xml绑定,你只需要逃避那些"
。例如。 var queryValue = @""Quantity"";
答案 1 :(得分:1)
假设您的密钥是Name,并且所有节点都包含该密钥,那么这应该有效:
string valImLookingFor = "\"Changed\"";
XDocument doc = XDocument.Load("file"); // or XDocument doc = XDocument.Parse(xmlString);
var node = doc.Descendants("UserVar").Where(x => x.Element("Name").Value == valImLookingFor).First();
那应该是你的节点,然后你可以提取你需要的子节点值。