Xelement.XPathSelectElement - PullRequest
       26

Xelement.XPathSelectElement

5 голосов
/ 14 декабря 2011

У меня есть следующая строка XPath

"(//DEAL_SETS/DEAL_SET/DEALS/DEAL/PARTIES/PARTY[ROLES/ROLE/
    ROLE_DETAIL/PartyRoleType='Borrower'])  
        [(ROLES/PARTY_ROLE_IDENTIFIERS/PARTY_ROLE_IDENTIFIER/
            PartyRoleIdentifier='1' or position() = 1)]/ROLES/ROLE/BORROWER/
                RESIDENCES/RESIDENCE/ADDRESS/PostalCode[../../RESIDENCE_DETAIL/
                    BorrowerResidencyType='Current']"

, который работает, когда я помещаю его в Altova XML Spy, и дает мне результат.

Но когда я использую его напрямую, как есть Xelement.XPathSelectElement(XPath), он не работает, но работает Xelement.XPathSelectElement(collective, nameSpaceManager), где Vector - это префикс пространства имен (скажем, с именем "ns") плюс моя строка XPath.

Но проблема в том, что я должен изменить строку XPath на что-то вроде этого

"(//ns:DEAL_SETS/ns:DEAL_SET/ns:DEALS/ns:DEAL/ns:PARTIES/ns:PARTY[ns:ROLES/
    ns:ROLE/ns:ROLE_DETAIL/ns:PartyRoleType='Borrower'])[(ns:ROLES/
        ns:PARTY_ROLE_IDENTIFIERS/ns:PARTY_ROLE_IDENTIFIER/
            ns:PartyRoleIdentifier='1' or position() = 1)]/ns:ROLES/
                ns:ROLE/ns:BORROWER/ns:RESIDENCES/ns:RESIDENCE/
                    ns:ADDRESS/ns:PostalCode[../../ns:RESIDENCE_DETAIL/
                        ns:BorrowerResidencyType='Current']"

Есть ли способ избежать необходимости ставить префикс пространства имен (ns:) на каждом узле.

Приносим извинения за то, что не разместили образец xml ранее, вы можете реплицировать тег Party и его элементы и заполнить их ложными данными. PartyRoleType дает мне информацию о том, какая это сторона может быть заемщиком, оценщиком и т. Д. Partyroleidentifier дает мне возможность провести различие между двумя сторона с одинаковыми типами партий, например, может быть 2 заемщика, идентификатор партии определяет их как 1 и 2

<?xml version="1.0" encoding="utf-8"?>
<MESSAGE xmlns="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xxxxReferenceModelIdentifier="3.0.0.263.12" xsi:schemaLocation="http://www.example.org/schemas C:\Subversion\xxx_3_0.xsd">
 <DEAL_SETS>
    <DEAL_SET>
      <DEALS>
        <DEAL>
          <PARTIES>
            <PARTY>
              <ROLES>
                <ROLE>
                  <PARTY_ROLE_IDENTIFIERS>
                     <PARTY_ROLE_IDENTIFIER>
                       <PartyRoleIdentifier>1</PartyRoleIdentifier>
                     </PARTY_ROLE_IDENTIFIER>
                  </PARTY_ROLE_IDENTIIERS>
                  <BORROWER>
                    <RESIDENCES>
                      <RESIDENCE>
                        <ADDRESS>
                        <PostalCode>56236</PostalCode>
                        </ADDRESS>
                      </RESIDENCE>
                    </RESIDENCES>
                  </BORROWER>
                  <ROLE_DETAIL>
                    <PartyRoleType>Borrower</PartyRoleType>
                  </ROLE_DETAIL>
                </ROLE>
              </ROLES>
            </PARTY>
          </PARTIES>
        </DEAL>
      </DEALS>
    </DEAL_SET>
  </DEAL_SETS>
</MESSAGE>

Ответы [ 2 ]

4 голосов
/ 14 декабря 2011

Согласно документации MSDN, когда вы звоните AddNamespace для вашего менеджера пространства имен, вы можете использовать String.Empty в качестве префикса для вашего URI пространства имен.Это должно позволить вам сделать выражение XPath без всех этих ns: префиксов.

Обновление :

ОК, я помню, как сталкивался с этой проблемой раньше.Поведение пустых префиксов пространства имен в выражениях XPath не согласуется с остальной частью пакета .NET XML.Есть некоторые доказательства того, что некоторые люди Microsoft знают об этой проблеме.См. эту ветку форума .Я еще немного поищу решения, но думаю, что вам придётся обходиться использованием префиксов пространства имен.

Обновление 2 :

Не стесняйтесь голосовать за эту ошибку Microsoft Connect , которую я только что создал.Я вижу, что они закрывали подобные ошибки в прошлом, но никто из них не фокусировался на проблемах юзабилити раньше.Возможно, мы получим некоторую поддержку с большим количеством голосов.

Обновление 3 :

Просто некоторые пояснения, моя ошибка не была и никогда не была о соответствии сСтандарты XPath , а точнее о юзабилити.Независимо от стандартов, пользователям нужен способ сделать запросы XPath с пространственным пространством имен XML более лаконичными, и в настоящее время это не поддерживается.Что касается поддержки стандартов, то в XSLT 2.0 есть способ сделать XPath 2.0 с пустыми префиксами пространства имен, связанными с URI пространства имен, и XMLSpy также имеет такую ​​возможность. В документации MSDN утверждается, что .NET имеет поддержку XPath 2.0 , но достоверность этого утверждения оспаривается.Можно утверждать, что .NET правильно реализует XPath 1.0, запретив модификацию того, что представляет пустой префикс.

1 голос
/ 15 декабря 2011

В настоящее время принят неправильный ответ !

Любой совместимый процессор XPath интерпретирует имя без префикса как принадлежащее «пространству без имен».

Это самый большой FAQ в XPath :

В XPath нет способа выбирать элементы в пространстве имен по умолчанию, используя их имена без префиксов.

Причина в том, что XPath считает, что любое нефиксированное имя находится в «no namespave», и ищет элементы с таким именем, которые находятся в «no namespace». Такие элементы не найдены и не выбраны, поскольку все элементы непустое пространство имен по умолчанию.

Вот точная цитата из спецификации W3C XPath 1.0 :

" если у QName нет префикса, тогда URI пространства имен будет нулевым ".

Существует два основных решения:

  1. Используя API, связанный с XPath, доступный на вашем языке программирования, зарегистрируйте связь между пространством имен по умолчанию и префиксом строки (скажем, "x"). Затем измените ваше выражение и замените все без префикса someElementName на x:someElementName. В .NET для регистрации ассоциации обычно необходимо создать объект XmlNamespaceManager, а для регистрации ассоциации необходимо использовать его метод AddNamespace(). Затем при вызове метода XPath-выбора экземпляр XmlNamespaceManager передается в качестве дополнительного аргумента.

  2. Если кто-то хочет избежать регистрации пространства имен по умолчанию, один из обходных путей вместо:

..

/a/b/c

использовать:

/*[name()='a']/*[name()='b']/*[name()='c']
...