XPath, который исключает некоторую часть выбранного элемента?

#xml #xpath

#xml #xpath

Вопрос:

XML:

     <root>
      <rows>
        <row hash="156458">
          <column name="Id">1</column>
          <column name="Nome">Evandro</column>
          <column name="CPF">98765432100</column>
        </row>
        <row hash="52458">
          <column name="Id">2</column>
          <column name="Nome">Everton</column>
          <column name="CPF">12345678900</column>
        </row>
      </rows>
    </root>
  

Запрос XPath:

./root/rows/row/column[@name='Nome'] | ./root/rows/row/column[@name='CPF']

XPath возвращает:

     <root>
      <column name="Nome">Evandro</column>
      <column name="CPF">98765432100</column>
      <column name="Nome">Everton</column>
      <column name="CPF">12345678900</column>
    </root>
  

Чего бы я хотел, чтобы XPath вернул:

     <root>
      <rows>
        <row hash="156458">
          <column name="Nome">Evandro</column>
          <column name="CPF">98765432100</column>
        </row>
        <row hash="52458">
          <column name="Nome">Everton</column>
          <column name="CPF">12345678900</column>
        </row>
      </rows>
    </root>
  

Я хочу, чтобы xpath сохранял структуру документа при выполнении запроса.

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

1. «Структура документа» поддерживается в объектной модели, с которой вы работаете. Таким образом, запрос вашего columns.parent фактически вернет объект ‘row’. Пусть вас не вводит в заблуждение «сериализованный вывод DOM, с которым вы работаете» при поиске в debugger / output

2. Вопросы, требующие кода, должны демонстрировать минимальное понимание решаемой проблемы. Укажите предпринятые решения, почему они не сработали и ожидаемые результаты . Смотрите также: Контрольный список вопросов по переполнению стека

3. Вы ожидаете слишком многого от XPath. Вместо этого используйте XSLT здесь.

4. Спасибо @kjhughes! Это способ. Мне просто нужно было, чтобы кто-нибудь сказал мне это.

5. И, извините, если я казался поспешным, но я не приходил сюда и не просил помощи без поиска раньше. Кажется, это не популярная тема на форумах.

Ответ №1:

XPath отлично подходит для выбора, но не для структурирования. Перейдите к полному XSLT для обоих. Простое преобразование на основе идентификаторов — это все, что вам нужно…

Учитывая этот ввод XML:

 <?xml version="1.0" encoding="utf-8" ?>
<root>
  <rows>
    <row hash="156458">
      <column name="Id">1</column>
      <column name="Nome">Evandro</column>
      <column name="CPF">98765432100</column>
    </row>
    <row hash="52458">
      <column name="Id">2</column>
      <column name="Nome">Everton</column>
      <column name="CPF">12345678900</column>
    </row>
  </rows>
</root>
  

Это преобразование XSLT:

 <xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="column[@name='Id']"/>

</xsl:stylesheet>
  

Создаст желаемый вывод XML:

 <?xml version="1.0" encoding="UTF-8"?>
<root>
   <rows>
      <row hash="156458">
         <column name="Nome">Evandro</column>
         <column name="CPF">98765432100</column>
      </row>
      <row hash="52458">
         <column name="Nome">Everton</column>
         <column name="CPF">12345678900</column>
      </row>
   </rows>
</root>
  

Примечания:

  • Первый шаблон — это шаблон идентификации; он будет копировать узлы из ввода в вывод, если более конкретный шаблон не переопределит его.
  • Второй шаблон — это переопределение для опускания Id column s.