2016-09-22 2 views
1

Теперь я прочитал много (возможно, все) сообщений об исключении элементов в XPath, и я просто не понимаю, как это работает. Я понятия не имею, почему. неXPath для исключения определенных элементов XML?

Скажем, я иметь следующую структуру:

<root> 
    <elemA> 
     Hello World! 
    </elemA> 
    <elemB> 
     This is awesome! 
     <elemC>Really!</elemC> 
    </elemB> 
</root> 

Нет Я хочу, чтобы все элементы, кроме elemC.

Исходя из того, что я прочитал, я попробовал следующее XPath:

Вариант 1:

//*[not(self::elemC)] 

Вариант 2:

//*[not(name()='elemC')] 

Вариант 3:

//*[name()!='elemC'] 

У меня нет подсказки, почему это не работает, но подозревают какую-то глупую ошибку. Если я делаю точную противоположность (т. Е. Оставляя not или !), XPath правильно выбирает элемент elemC.

Результат должен быть таким:

<root> 
    <elemA> 
     Hello World! 
    </elemA> 
    <elemB> 
     This is awesome! 
    </elemB> 
</root> 
+0

Это хорошо выраженный вопрос, затрагивающий класс проблем, которые XPath (один) не может решить. См. [Мой ответ ниже] (http://stackoverflow.com/a/39640786/290085) для получения дополнительной информации. – kjhughes

ответ

2

XPath для выбора. То, что вы хотите выбрать, не существует в вашем XML-документе.

Для создания выходного документа XML на основе входного XML-документа вам нужен другой инструмент, такой как XSLT. XSLT может генерировать свой желаемый результат тривиальным через тождественное преобразование, дополненной простой шаблон, который подавляет копирование элемента, который вы не хотите (elemC): одна

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="elemC"/> 
</xsl:stylesheet> 

XPath не может помочь вам.

+1

Большое спасибо. Это действительно помогло прояснить. Интересно, почему я всегда понимал, что другие вопросы касаются «исключить элемент x с XPath», чтобы означать то же, что я имел в виду. Во всяком случае, я попробую XSLT. Кажется, что это не слишком сложно, как только вы знаете, какой инструмент использовать. –

+0

Вы можете, конечно, исключить узлы из списка других выбранных узлов, но вы не можете выбрать 'elemB' без дочернего' elemC', потому что в вашем XML нет такого 'elemB'. – kjhughes

Смежные вопросы