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

#xml #xpath #xpath-2.0

Вопрос:

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 фактически вернет объект «строка». Не обманывайтесь «сериализованным выводом DOM, с которым вы работаете» при просмотре отладчика/вывода

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.