Xpath 1.0 возвращает первый узел к предку

#xpath

#xpath

Вопрос:

Мой XML, как показано ниже :

 <Query>
  <Comp>
    <Pers>
        <Emp>
            <Job>
                <Code>Not selected</Code>
            </Job>
        </Emp>
        <Emp>
            <Job>
                <Code>selected</Code>
            </Job>
        </Emp>
    </Pers>
  </Comp>
</Query>
  

У меня есть XPath : /Query/Comp /Pers /Emp /Job[Code=’selected’]/../../../..

В результате должен быть только один < Emp>, удовлетворяющий условию

 <Query>
  <Comp>
    <Pers>
        <Emp>
            <Job>
                <Code>selected</Code>
            </Job>
        </Emp>
    </Pers>
  </Comp>
</Query>        
  

Как я мог бы получить результат?
Система не работает с предком::*. Я должен использовать ‘/..’ для заполнения предка.

Ответ №1:

Вам не обязательно использовать ancestor here для получения <emp> тега, следующий expath должен выбрать любой <emp> тег, который соответствует вашим критериям:

/Query/Comp/Pers/Emp[Job[Code='selected']]

Примечание: Вы говорите, что ваш результат должен быть единичным, что будет правильным в данном случае, но это выражение вернет все узлы, соответствующие вашим критериям


Редактировать:

Вы заявили, что используете XSLT, и привели мне небольшой фрагмент ниже, но я все еще не уверен на 100% в вашей реальной структуре. Вы можете использовать XPath для идентификации всех узлов, которые не равны selected , а затем использовать XSLT для копирования всего, кроме них.

 // Copy's all nodes in the input to the output
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>

// Matches specifically the Emp records that are not equal to selected and 
// applies no action to them to they do not appear in the output
<xsl:template match="/Query/Comp/Pers/Emp[Job[Code!='selected']]" />
  

Два приведенных выше шаблона преобразуют ваш ввод в желаемый результат!

Комментарии:

1. Спасибо @Dan Gardner. Я попробовал ваш XPath, результатом был <Emp> <Job> <Code>. Но мне нужно, чтобы результат заполнял все узлы из тега <Query>. для ie :<Запрос><Comp><Человек><Emp><Задание><Код>выбрано</Code></Job></Emp></Человек></Query>

2. Ах, хорошо, теперь я понимаю, извините. Я не верю, что то, о чем вы просите, возможно, XPath может выбирать только целые деревья узлов, он не может манипулировать структурой, которую он возвращает. Можно было бы достичь того, чего вы хотели, используя XSLT, я мог бы помочь со структурой этого, если хотите? Не могли бы вы предоставить более подробную информацию о более крупной проблеме, которую вы пытаетесь решить, я мог бы, возможно, внести несколько предложений по альтернативному подходу!

3. Я использую XSLT перед XPath для фильтра. Я пытался не изменять XSLT. Поскольку XPath невозможен. Мне нужно настроить отображение в XSLT.

4. @Handy можете ли вы опубликовать код XSLT? Я могу либо отредактировать свой ответ, чтобы объяснить и использовать XSLT, либо вы могли бы ответить на свой собственный вопрос с объяснением, чтобы другие с тем же вопросом в будущем могли увидеть решение 🙂

5. Вот мой простой XSLT-код для выбора первой строки на основе критериев соответствия. <xsl:для каждого select=»Запрос/Comp/Pers/Emp/Job[Code=’selected’][1]»>