SelectNodes中的XPath选择存在特定孙子节点的所有节点,而不管其值如何

时间:2013-08-09 11:27:35

标签: c# xml xpath xsd

我有一个XSD文档,我需要选择与某个布局匹配的所有节点。

以下是XSD的片段:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="MachineParameters">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="stMachineParameters"
         minOccurs="1"
         maxOccurs="1">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="CPSPEED"
                     minOccurs="1"
             maxOccurs="1">
                  <xsd:annotation>
        <xsd:documentation>CPSPEEDDesc</xsd:documentation>
        <xsd:appinfo>false</xsd:appinfo>
          </xsd:annotation>
          <xsd:simpleType>
                    <xsd:restriction base = "xsd:decimal">
                    </xsd:restriction>
                  </xsd:simpleType>
                </xsd:element>  
                <xsd:element name="STVARZPARAMS"
                     minOccurs="1"
                             maxOccurs="1">
                  <xsd:complexType>
                    <xsd:sequence>
                      <xsd:element name="VARIABLEZFASTVELOCITY">
                        <xsd:annotation>
                          <xsd:documentation>VARIABLEZFASTVELOCITYDesc</xsd:documentation>
                          <xsd:appinfo>false</xsd:appinfo>
                        </xsd:annotation>
                        <xsd:simpleType>
                          <xsd:restriction base = "xsd:decimal">
                            <xsd:minInclusive value="0" />
                            <xsd:maxInclusive value="1" />
                          </xsd:restriction>
                        </xsd:simpleType>
                      </xsd:element>

等等。

我正在尝试编写一些C#代码来运行我的整个文档,并返回一个已指定xsd:appinfo的任何元素的列表,无论其值如何。

我一直在努力解决这个问题并觉得我很接近,但到目前为止我还没有找到正确的Xpath查询(我之前没有使用过它)。

这是C#:

elementInfo = new Dictionary<string, DictionaryInfo>();

XmlNodeList nodeList;
XmlNode root = xmlDocSchema.DocumentElement;


try
{
    // the presence of an annotation/appinfo for the element is being used to identify it as a value element
    XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocSchema.NameTable);
    xmlNamespaceManager.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
    nodeList = root.SelectNodes("/*/element[/annotation/appinfo='false' or /annotation/appinfo='true']", xmlNamespaceManager);
}
catch (System.Xml.XPath.XPathException ex)
{
    MessageBox.Show(string.Format("Xpath exception: {0}", ex.Message));
    nodeList = null;
}
catch (Exception ex)
{
    MessageBox.Show(string.Format("General exception: {0}", ex.Message));
    nodeList = null;
}

有人可以建议我哪里出错(以及如何正确行事!)?

1 个答案:

答案 0 :(得分:1)

我想你想用

"//xsd:element[xsd:annotation/xsd:appinfo]"

作为你的xpath。您使用的内容有一些变化:

  • //element是选择文档中任何级别的元素的语法。 /*/element仅选择作为根节点子节点的元素。

  • 您需要在XPath中使用该命名空间的每个元素上使用名称空间前缀。

  • 如果您对谓词不感兴趣,则无需检查谓词的值;只需指定元素名称(或路径)检查是否存在。

  • 使用/启动谓词很少是您想要的。它忽略当前上下文,并尝试匹配从文档根开始的谓词(在您的情况下,谓词[/annotation/appinfo]仅在根节点是注释元素且具有appinfo子项时才为真。)