2014-09-26 3 views
8

Что мне нужно, похоже, не соответствует тому, что касается других статей подобного названия.XPath 1.0 эксклюзивное выражение или набор узлов

Мне нужно, используя Xpath 1, чтобы иметь возможность получить узел a или узел b, в порядке исключения. То есть узел a, если он существует, иначе узел b.

выражение XPath, такие как:

expression | expression

получите меня, как в случае, если они оба существуют. это не то, что я хочу.

Я мог бы пойти:

(expression | expression)[last()]

Что делает фактически ГГЕТ, что мне нужно (в моем случае), но, кажется, немного неэффективным, так как он будет оценивать обе стороны выражения, прежде чем выбирается последний результат. Я надеялся на выражение, которое перестанет работать, как только левая сторона удастся.

Более конкретный пример XML

<one> 
    <two> 
    <three>hello</three> 
    <four>bye</four> 
    </two> 
    <blahfive>again</blahfive> 
</one> 

и XPath, который работает (но неэффективный):

(/one/*[starts-with(local-name(.), 'blah')] | .)[last()]

Чтобы было ясно, я хотел бы, чтобы захватить непосредственный дочерний узел «один», который начинается с «бла». Однако, если он не существует, мне нужен только текущий узел. Если узел 'blah' существует, мне не нужен текущий узел.

Есть ли более эффективный способ достичь этого?

+1

+1 Интересный вопрос и ИМХО очень элегантное решение для него. Не могли бы вы рассказать о том, почему в этом случае вы заинтересованы в производительности? Судя по моему опыту, потеря производительности в листах XSLT обусловлена ​​другими причинами. –

+0

Привет. На самом деле это приложение для Java. Приложение использует выражения xpath (загруженные из файла конфигурации) для извлечения значений из XML-документа. Приложение будет получать много таких документов каждую минуту, поэтому эффективность важна для улучшения (или даже достижения) надежного сквозного доступа. – svaens

+2

Если это встроено в Java, вы могли бы/могли бы управлять вспомогательными выражениями, явно выполняя второй XPath только в том случае, если первый не даст результата, не так ли? –

ответ

1

Мне нужно, используя Xpath 1, чтобы иметь возможность получить узел a или узел b, , извини, в указанном порядке. То есть узел a, если он существует, в противном случае, узел b.

выражение XPath, такие как:

expression | expression

получите меня, как в случае, если они оба существуют. это не то, что я хочу.

Я мог бы пойти:

(expression | expression)[last()]

Что делает фактически ГГЕТ, что мне нужно (в моем случае),

Это утверждение не верно.

Вот пример.Давайте этот XML-документ:

<one> 
    <a/> 
    <b/> 
</one> 

Выражение1:

/*/a 

ВЫРАЖЕНИЕ2:

/*/b 

Ваше составное выражение:

(Expression1 | Expression2)[last()] 

подставляя два выражения выше:

(/*/a | /*/b)[last()] 

И это выражение на самом деле выбирает b - не a - потому что b последний из двух в порядке документа.

Теперь, здесь есть выражение, которое выбирает только a, если он существует, и выбирает b только если a не существует, - независимо от того документа:

/*/a | /*/b[not(/*/a)] 

Когда это выражение вычисляется на XML выше, он выбирает a, независимо от его порядка документа - попробуйте выполнить обмен в документе XML над местами a и b, чтобы подтвердить, что в обоих случаях выбранным элементом является a.

Подводя итог, одно выражения, которое выбирает разыскиваемый узел независимо от того документа является:

Expression1 | Expression2[not(Expression1)] 

Применит это общее выражение в вашем случае:

Выражение1:

/one/*[starts-with(local-name(.), 'blah')] 

Expression2 is:

self::node() 

разыскиваемого выражение (после подстановки Выражение1 и Выражение2 в приведенном выше общем выражении) составляет:

/one/*[starts-with(local-name(.), 'blah')] 
| 
    self::node()[not(/one/*[starts-with(local-name(.), 'blah')])] 
Смежные вопросы