これは難しいことではないようですが、今は行き詰まっています。特定のXPathクエリ文字列に一致するノードから特定の属性の属性値を取得しようとしています。ここに私がこれまで持っているものがあります:
public static IEnumerable<string> GetAttributes(this XmlDocument xml,
string xpathQuery, string attributeName)
{
var doc = new XPathDocument(new XmlNodeReader(xml));
XPathNavigator nav = doc.CreateNavigator();
XPathExpression expr = nav.Compile(xpathQuery);
XPathNodeIterator iterator = nav.Select(expr);
while (iterator.MoveNext())
{
XPathNavigator curNav = iterator.Current;
if (curNav.HasAttributes)
{
XmlNode curNode = ((IHasXmlNode)curNav).GetNode();
if (null != curNode)
{
XmlAttribute attrib = curNode.Attributes[attributeName];
if (null != attrib)
{
yield return attrib.Value;
}
}
}
}
}
これは現在、例外をスローします:
System.InvalidCastException: 'MS.Internal.Xml.Cache.XPathDocumentNavigator'タイプのオブジェクトを 'System.Xml.IHasXmlNode'タイプにキャストできません。
私はこれを間違っているのでしょうか?一致するノードから属性値を取得する簡単な方法はありますか?
次のxmlの場合:
<root>
<elem att='the value' />
</root>
このC#コードで「値」テキストを取得できます
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(text);
Console.WriteLine(xdoc.SelectSingleNode("/root/elem/@att").Value);
.net 3.5以降を使用している場合は、linq to Xmlを使用できます
特定のXMLドキュメント
<?xml version="1.0" encoding="utf-8" ?>
<root>
<storedProcedures>
<storedProcedure name="usp_GET_HOME_PAGE_DATA">
<resultSet name="Features"/>
<resultSet name="Highlights"/>
</storedProcedure>
<storedProcedure name="usp_GET_FEATURES" />
<storedProcedure name="usp_GET_FEATURE" />
<storedProcedure name="usp_UPDATE_FEATURE" />
<storedProcedure name="usp_GET_FEATURE_FOR_DISPLAY">
<resultSet name="CurrentFeature"/>
<resultSet name="OtherFeatures"/>
</storedProcedure>
<storedProcedure name="usp_GET_HIGHLIGHT_TITLES">
<resultSet name="Highlights"/>
</storedProcedure>
</storedProcedures>
</root>
次のlinq式は、すべてのstoredProcedureノードの「name」属性の値を取得します
XDocument xDcoument = XDocument.Load(xmlStoredProcSchemeFile);
var storedProcedureNames = from doc in xDcoument.Descendants("storedProcedure")
select doc.Attribute("name").Value;
通常のXPath構文を使用することもできます。以下のコードでは、変数ノードは「usp_GET_HOME_PAGE_DATA」という名前で識別されるノードを保持し、属性変数は選択されたノードとその子のすべての子ノード(属性)を保持します。
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(@"C:\inetpub\wwwroot\ASPNETBuilder\BusinessLayer\DataAccessCodeGenerationSchema.xml");
var node = xmlDocument.DocumentElement.SelectSingleNode("./storedProcedures/storedProcedure[@name='usp_GET_HOME_PAGE_DATA']");
var attributes = node.SelectNodes("./resultSet/@name");
スローされる例外の初期問題の解決策...
var doc = new XPathDocument(new XmlNodeReader(xml));
置き換える必要があります...
var doc = new XmlDocument();
doc.load(*you can either specify the path to the file, the string out of which the xml document is to be generated or specify an xmlreader, look for more overloads*);
これは例外をスローせず、コードは問題なく動作します。