Простой рекурсивный запрос XQuery, дочерний для верхнего родителя в XML - PullRequest
4 голосов
/ 08 апреля 2019

Ввод xml

<req>
  <family>
    <person>
      <id>id1</id>
      <name>name1</name>
      <mother>mother1</mother>
      <age>age1</age>
    </person>
    <person>
      <id>id2</id>
      <name>name2</name>
      <mother>mother2</mother>
      <age>age2</age>
    </person>
    <person>
      <id>id4</id>
      <name>mother3</name>
      <mother>mother4</mother>
    </person>
    <person>
      <id>id3</id>
      <name>mother2</name>
      <mother>mother3</mother>
      <age>age3</age>
    </person>
  </family>
</req>

Не могли бы вы, пожалуйста, помочь мне, как получить старшего parrent 'person' с существующим элементом 'age' для каждого 'req / family /person '?

My follow xquery

declare function local:recons($family as element(*), $person as element(*))
    as element(*) {
    let $parrent := for $p in $family/person
    where $p/name=$person/mother
    return local:recons($family,$p)
    return
    <person>
    {$person/*}
    <parrent>{$parrent}</parrent>
    </person>
};

declare function xf:MyTest($inputXML as element(*))
    as element(*) {
       <res>
       <family>
       {
       for $person in $inputXML/family/person
       return local:recons($inputXML/family,$person)
       }
       </family>
       </res>
};

declare variable $inputXML as element(*) external;

xf:MyTest($inputXML)

Ожидаемый результат

<res>
  <family>
    ...
    <person>
      <id>id2</id>
      <name>name2</name>
      <mother>mother2</mother>
      <age>age2</age>
      <parrent>
        <person>
          <id>id3</id>
          <name>mother2</name>
          <mother>mother3</mother>
          <age>age3</age>
          <parrent/>
        </person>
      </parrent>
    </person>
    ...
  </family>
</res>

Фактический результат

<res>
  <family>
    ...
    <person>
      <id>id2</id>
      <name>name2</name>
      <mother>mother2</mother>
      <age>age2</age>
      <parrent>
        <person>
          <id>id3</id>
          <name>mother2</name>
          <mother>mother3</mother>
          <age>age3</age>
          <parrent>
            <person>
              <id>id4</id>
              <name>mother3</name>
              <mother>mother4</mother>
              <parrent/>
            </person>
          </parrent>
        </person>
      </parrent>
    </person>
    ...
  </family>
</res>

Я пытался использовать ancestor и xpath наподобие '$ parrent // person [fn: exist (age)]', безуспешно.Я пытался использовать ancestor и xpath, например '$ parrent // person [fn: exist (age)]', безуспешно.

1 Ответ

1 голос
/ 08 апреля 2019

Настройте условие where для вашего local:recons(), чтобы убедиться, что вы выбираете $parrent (разве этот элемент и переменная не должны быть написаны как родительский?), Если у него есть age и его совпадения name $person/mother

Вы можете легко сделать это с помощью фильтра предикатов:

where $p[age]/name = $person/mother    

Применительно к функции:

declare function local:recons($family as element(*), $person as element(*))
    as element(*) {
    let $parrent := for $p in $family/person
      where $p[age]/name = $person/mother
      return local:recons($family,$p)
    return
      <person>
        {$person/*}
        <parrent>{$parrent}</parrent>
      </person>
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...