Как можно выбрать тег XML, содержащий указанный тег c XML с конкретным текстом c внутри с использованием регулярных выражений? - PullRequest
1 голос
/ 14 февраля 2020

У меня есть XML текст. В этом тексте XML у меня есть теги с именем <pskc:KeyPackage>, этот тег может содержать или не содержать разные теги, и один из этих тегов может быть <pskc:IssueNo>1</pskc:IssueNo>. С помощью регулярных выражений я хочу выбрать все теги <pskc:KeyPackage>, которые содержат тег <pskc:IssueNo>1</pskc:IssueNo>. Как я могу выполнить sh это?

см. Регулярное выражение для текущей ссылки: https://regex101.com/r/7HICeu/2

Это мой пример ввода:

<pskc:KeyPackage>  

 <testTag>val1</testTag>

  <pskc:IssueNo>1</pskc:IssueNo>

  <testTag2>val2</testTag2>

</pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>2</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>3</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>1</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>2</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>3</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>1</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>2</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>3</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>1</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>2</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>3</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>1</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>2</pskc:IssueNo>

  </pskc:KeyPackage>
  <pskc:KeyPackage>

      <pskc:IssueNo>3</pskc:IssueNo>

  </pskc:KeyPackage>

я хочу использовать следующие теги:

<pskc:KeyPackage>  

 <testTag>val1</testTag>

  <pskc:IssueNo>1</pskc:IssueNo>

  <testTag2>val2</testTag2>

</pskc:KeyPackage>

и я также хочу сопоставить каждый тег, который выглядит следующим образом:

  <pskc:KeyPackage>

      <pskc:IssueNo>1</pskc:IssueNo>

  </pskc:KeyPackage>

Я хочу еще раз сказать, что тег <pskc:KeyPackage> будет содержать много разных тегов, как в следующем примере:

<pskc:KeyPackage>  

 <testTag>val1</testTag>

  <pskc:IssueNo>1</pskc:IssueNo>

  <testTag2>val2</testTag2>

</pskc:KeyPackage>

Я хочу обработать весь тег <pskc:KeyPackage>, только если он содержит <pskc:IssueNo>1</pskc:IssueNo>. Как я могу выполнить sh это?

PS Я также пробовал много разных регулярных выражений, одно из них следующее регулярное выражение: <pskc:KeyPackage>[\s\S]*<pskc:IssueNo>1<\/pskc:IssueNo>[\s\S]*<pskc:KeyPackage>, но оно объединяет целую строку xml.

Спасибо

1 Ответ

2 голосов
/ 14 февраля 2020

Это работает :

/<pskc:KeyPackage>((?!<\/pskc:KeyPackage>).)*<pskc:IssueNo>1<\/pskc:IssueNo>.*?<\/pskc:KeyPackage>/gs

(Я не знаю всех разновидностей регулярных выражений, но похоже, что это работает для Perl, JS и Python .)

Как это работает:

  • соответствует <pskc:KeyPackage>,
  • , за которым следует любое количество (первое *) любых символов (первое .), включая переводы строк (флаг s), каждый из которых соответствует, где </pskc:KeyPackage> соответствует , а не ((?!…)),
  • , за которым следует <pskc:IssueNo>1</pskc:IssueNo>.
  • Затем он также соответствует ближайшему (.*?) закрытию </pskc:KeyPackage>.

Другие две детали:

  • / с для экранирования, \/,
  • , в зависимости от вашего приложения, вы можете использовать не захватывающие скобки для первой группы (измените первые ( на (?:), единственной целью которых является позвольте вам применить первый * к нему.
...