Xs: документация узла ближайшего предка элемента xs: - PullRequest
3 голосов
/ 31 января 2011

У меня есть документ wsdl, фрагмент которого показан ниже ...

<xs:complexType name="CustomerNameType">
  <xs:annotation>
    <xs:documentation>Structure for customer name</xs:documentation>
  </xs:annotation>
  <xs:sequence>
    <xs:element name="FullName" minOccurs="0">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:maxLength value="60"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:element>
    <xs:element name="Forenames" minOccurs="0">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:maxLength value="60"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

Я знаю xs: element / @ name, и я хотел бы получить ближайший элемент xs: Documentation.

Используя приведенный выше пример, я знаю, что xs: element / @ name = "FullName", и я хотел бы получить текст "Структура для имени клиента" из ближайшего узла xs: документации!

Я попытался изменить несколько примеров, которые я нашел в stackoverflow (и других сайтах), но ни один из них не работает.Типичный: 0).

Приветствия.

Спасибо за ответы, ребята ... надеюсь, это пригодится ...

public static string DecryptStupidCapsError(string sOriginalErrorMessage)
{
    string sProblem = sOriginalErrorMessage.Substring(sOriginalErrorMessage.IndexOf("---> System.Xml.Schema.XmlSchemaException: ") + "---> System.Xml.Schema.XmlSchemaException: ".Length);
    sProblem = sProblem.Substring(0, sProblem.IndexOf("An error occurred"));

    string sElementName = sProblem.Substring(sProblem.IndexOf(":") + 1);
    sElementName = sElementName.Substring(sElementName.IndexOf(":") + 1);
    sElementName = sElementName.Substring(0, sElementName.IndexOf("'"));

    XmlDocument xd = new XmlDocument();
    xd.LoadXml(Properties.Resources.ServiceRequest_Service_74b1);

    XmlNamespaceManager xnsm = new XmlNamespaceManager(xd.NameTable);
    XPathDocument x = new XPathDocument(new StringReader(Properties.Resources.ServiceRequest_Service_74b1));
    XPathNavigator foo = x.CreateNavigator();
    foo.MoveToFollowing(XPathNodeType.Element);
    IDictionary<string, string> whatever = foo.GetNamespacesInScope(XmlNamespaceScope.All);

    foreach (KeyValuePair<string, string> xns in whatever)
    {
        xnsm.AddNamespace(xns.Key, xns.Value);
    }

    XmlNodeList xnl = xd.SelectNodes("//xs:element[@name='" + sElementName + "']", xnsm);

    StringBuilder sb = new StringBuilder();

    sb.AppendLine("CAPS has reported a (cryptic) error whilst validating the data you entered.");
    sb.AppendLine();
    sb.AppendLine("The following summary should enable you to determine what has caused the '" + sElementName + "' data to be invalid.");
    sb.AppendLine("----------");

    string sLast = string.Empty;
    foreach (XmlElement xe in xnl)
    {
        StringBuilder sbLast = new StringBuilder();
        XmlElement xeDocumentation = (XmlElement)xe.OwnerDocument.SelectSingleNode("(//xs:element[@name='" + sElementName + "']/ancestor-or-self::*/xs:annotation/xs:documentation)[last()]", xnsm);
        if (xeDocumentation.InnerText == sLast) continue;

        sbLast.AppendLine(sElementName + " AKA " + xeDocumentation.InnerText + ": ");
        sbLast.AppendLine("has the following validation rules:");
        XDocument xdoc = XDocument.Parse(xe.OuterXml);
        sbLast.AppendLine(xdoc.ToString());
        sbLast.AppendLine("----------");

        sb.AppendLine(sbLast.ToString());
        sLast = xeDocumentation.InnerText;
    }


    return sb.ToString();
}

В основном, sOriginalErrorMessage = XmlSchemaException.ToString () и Properties.Resources.ServiceRequest_Service_74b1 - это wsdl, с которым были проверены данные.Эта функция (которой не хватает регулярных выражений!) Дает пользователю гораздо лучшие подсказки о том, что вызвало ошибку проверки, в отличие от старого исключения XmlSchemaException.

Еще раз спасибо.

Ответы [ 2 ]

5 голосов
/ 31 января 2011

Элемент xs:element с @name, равным "FullName", не имеет элемента xs:documentation предка , но предшествует единице.

Итак, вы можете использовать:

//xs:element[@name='FullName']/preceding::xs:documentation[1]

Примечание : я использовал начальный оператор //, потому что я не знаю, как глубоко в схему вы хотите перейти.

2 голосов
/ 31 января 2011

Следующий XPATH вернет документацию указанного элемента и всю родительскую документацию. Я думаю, что ответ Алехандро может вернуть документ родного брата, который может быть менее интересен для вас в другой схеме.

(//xs:element[@name='orderRequest']
     /ancestor-or-self::*
         /xs:annotation
             /xs:documentation)[last()]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...