xpath знайти, якщо вузол існує


201

Використовуючи xpath запит, як з’ясувати, чи існує вузол (тег) взагалі?

Наприклад, якщо мені потрібно було переконатися, що сторінка веб-сайту має правильну основну структуру, як / html / body та / html / head / title


Можливо, краще використовувати XML-схему з обов'язковим зазначенням елементів? Тому переконайтеся, що документ використовує його чи ні.
абатищев

Відповіді:


321
<xsl:if test="xpath-expression">...</xsl:if>

так, наприклад

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>

41
Здивований таким високим рейтингом, враховуючи, що питання взагалі не визначає використання XSLT.
tjmoore

Це приголомшливо, але що робити, якщо я хотів перевірити, чи існує він АБО порожній?
SearchForKnowledge

3
@SearchForKnowledge, ви, ймовірно, можете задати це питання як нове запитання в SO, але як швидкий посібник: html/body and not(html/body/node())(тобто просто перевірити, чи існує він, і він не містить дочірніх вузлів або текстових вузлів).
Авель

71

Спробуйте наступний вираз: boolean(path-to-node)


3
Це саме те, що мені було потрібно при використанні XPath в Python з lxml.
Ієн Самуель Маклін Старший

1
Це підготувало частування під час створення Правил і правил дії в рамках InfoPath 2010.
Меренцо,

3
Це правильна відповідь у тому сенсі, що це насправді запит XPath, на відміну від більшості інших відповідей.
Пол Етертон

48

Патрік правильний, як у використанні xsl:if, так і в синтаксисі для перевірки наявності вузла. Однак, як випливає з відповіді Патріка, немає xsl, еквівалентного if-then-else, тому якщо ви шукаєте щось більше, як якщо-то-інше, вам зазвичай краще використовувати xsl:chooseта xsl:otherwise. Так, синтаксис прикладу Патріка спрацює, але це альтернатива:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>

+1 для того, щоб помітити if-then-else, а як же if-else if-else? У відповіді davenpcj чи можу я помістити його test="somexpath"у 2-е місце, коли це зробити if-else if-else?
AabinGunz

3
@Abhishek Так, ви можете поставити більше xsl: коли з іншими умовами і мати заяву з кількома гілками. Подумайте про це більше як SELECT, ніж як if-then-else, з xsl: інакше як за замовчуванням:.
davenpcj

Це приголомшливо, але що робити, якщо я хотів перевірити, чи існує він АБО порожній?
SearchForKnowledge

13

Можливо, краще використовувати вибір, не потрібно вводити (або, можливо, неправильно вводити) свої вирази не один раз, і дозволяє вам слідувати додатковим різним поведінкам.

Я дуже часто використовую count(/html/body) = 0, оскільки конкретна кількість вузлів цікавіше набору. Наприклад ... коли неочікувано більше 1 вузла, який відповідає вашому вираженню.

<xsl:choose>
    <xsl:when test="/html/body">
         <!-- Found the node(s) -->
    </xsl:when>
    <!-- more xsl:when here, if needed -->
    <xsl:otherwise>
         <!-- No node exists -->
    </xsl:otherwise>
</xsl:choose>

Як зазначено у наведеному вище коді, більше xsl: коли можна додавати пропозиції для зміни поведінки та обробки різних умов різними способами.
davenpcj

count(/html/body) = 0 геній! : DI використовуйте його як /html[count(/body)=0]/someNodeдля вибору, someNodeколи /body(або що завгодно) відсутнє
Стефан Рогін

1
@clickstefan, /html[count(/body)=0]ніколи нічого не вибере, у XML не може бути двох кореневих вузлів. Можливо, ви мали на увазі /html[count(body)=0], що було б те саме /html[not(body)], що або /html[not(exists(body))].
Абель

@Abel так, / html [count (// body) = 0] або як ви сказали, ганебно, але так, я не наводив належного прикладу
Стефан Рогін

4

Я працюю в Ruby і за допомогою Nokogiri я отримую елемент і дивлюсь, чи є результат нульовим.

require 'nokogiri'

url = "http://somthing.com/resource"

resp = Nokogiri::XML(open(url))

first_name = resp.xpath("/movies/actors/actor[1]/first-name")

puts "first-name not found" if first_name.nil?

3

Варіант при використанні xpath в Java за допомогою count ():

int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.