Как выбрать дочерний элемент на основе значения без учета порядка и без использования цикла FOR в XPATH - PullRequest
1 голос
/ 17 декабря 2010

Вопрос довольно большой :) Но это то, чего я хочу достичь.

Я зацикливаюсь на каждом родительском элементе (сотруднике), а затем на каждом дочернем элементе родителя (зависимого) и нуждаюсьчтобы сопоставить их вместе, используя третий элемент, называемый Election, в зависимости от того, совпадает ли зависимый идентификатор (Dep_ID) в двух отдельных строках.

Таким образом, XML выглядит так:

<Employee>
 <Dependent><Depedent_ID>101</Depedent_ID> </Dependent>
 <Dependent><Depedent_ID>102</Depedent_ID> </Dependent>
 <Dependent><Depedent_ID>103</Depedent_ID> </Dependent>
 <Election Status="Current">       
  <Dependent> 
   <Dep_ID @id=102/>
  </Dependent>
  <Dependent> 
   <Dep_ID @id=103/>
  </Dependent>
 </Election> 
  <Election Status="Previous">
  <Dependent> 
    <Dep_ID @id=103/>
  </Dependent>
  <Dependent> 
   <Dep_ID @id=102/>
  </Dependent>
  <Dependent> 
   <Dep_ID @id=101/>
  </Dependent>
 </Election>
</Employee>

Итак, точный вопросдля каждого иждивенца, посмотрите, был ли он там на предыдущих выборах, но не на текущих выборах.

Мой существующий код действует так, как будто он проверяет только первого зависимого.Например: мне нужен способ написать выражение xpath, чтобы сначала проверить, равен ли какой-либо из Dep_Ids в элементе Previous Elections значение 100, а затем проверить, не равен ли 100 Dep_Ids в текущих выборах.Но существующий код проверяет первый элемент.Как заставить мой код проверять все дочерние «зависимые» элементы в элементе «Выборы»?

Я уверен, что это что-то простое, но я не могу его получить.

Мойсуществующий код: (Я зацикливаюсь на дочернем зависимом элементе элемента employee на данный момент)

<xsl:if test="parent::*/wd:Benefit_Elections[(wd:Status/@wd:Descriptor='Previous')]/wd:Benefit_Dependents/wd:ID[@wd:type='Dependent_ID']=wd:Dep_ID">
   <xsl:if test="count(parent::*/wd:Benefit_Elections[wd:Status/@wd:Descriptor='Current'] /wd:Benefit_Dependents)=0 or parent::*/wd:Benefit_Elections[wd:Coverage_Type='Medical/Vision' and (wd:Status/@wd:Descriptor='Current')]/wd:Benefit_Dependents/wd:ID[@wd:type='Dependent_ID']!=wd:Dep_ID">

UPDATE Dimitre попросил меня упростить / сделать отступ для кода выше для лучшей читаемости.Как я уже говорил, у меня есть два утверждения, в которых эти проверки должны быть сделаны.Я также открыт для использования одного оператора, но я не могу заставить его работать.

На этом этапе код зацикливается на каждом дочернем зависимом элементе элемента Employee.Затем код зацикливается на элементе «Выборы преимущества» родительского элемента Employee и проверяет, равен ли текущий зависимый идентификатор любому из дочерних зависимых идентификаторов элемента выбора преимущества со статусом «предыдущий».Это работает не во всех случаях, так как эта проверка происходит только для первого зависимого элемента «выборов пособия».

Упрощенный код моего заявления: Я в цикле за каждым сотрудником/ Зависимый в этой точке.

<xsl:if test=
 "parent::*/Election[(Status='Previous')] 
                             /Dependent/Dep_ID/@id=Depedent_ID">
  <!--  DO SOMETHING HERE if above condition is true but this is checking only the first "Dependent element.--> 

Так что мой вопрос действительно: «В приведенном выше утверждении, как я могу проверить, равен ли Dependent_ID ЛЮБОМУ из Election / Dependent / Dep_ID / @ id родителя? Iнадеюсь, это прояснит вопрос. Спасибо.

Итак, еще раз в качестве примера, я хочу, чтобы это условие возвращало TRUE при проверке на Depedent_ID = 101, потому что 101 не присутствует на текущих выборах, но присутствовална предыдущих выборах.

1 Ответ

2 голосов
/ 17 декабря 2010

Использовать :

/*/Dependent
      [@id = ../Election[@Status='Previous']
                                /Dependent/Dep_ID
     and
       not(@id = ../Election[@Status='Current']
                                /Dependent/Dep_ID)
      ]

Выбирает все элементы Dependent, атрибут id которых равен одному из элементов

/*/Election[@Status='Previous']/Dependent/Dep_ID

и имеетне равен ни одному из элементов

/*/Election[@Status='Current']/Dependent/Dep_ID

.

Когда это выражение XPath оценивается по отношению к предоставленному документу XML (исправлено, так как оно было серьезно искажено):

<Employee>
 <Dependent id="100"/>
 <Dependent id="101"/>
 <Dependent id="102"/>
 <Election Status="Current">
  <Dependent>
    <Dep_ID>101</Dep_ID>
  </Dependent>
  <Dependent>
    <Dep_ID>102</Dep_ID>
  </Dependent>
 </Election>
  <Election Status="Previous">
  <Dependent>
    <Dep_ID>100</Dep_ID>
  </Dependent>
  <Dependent>
    <Dep_ID>103</Dep_ID>
  </Dependent>
  <Dependent>
    <Dep_ID>102</Dep_ID>
  </Dependent>
 </Election>
</Employee>

Точно выбранный элемент выбран :

<Dependent id="100"/>

ОБНОВЛЕНИЕ : ФП заявил в комментарии, что он являетсяначинающий и не знает, как использовать это выражение XPath.

Вот один полный пример кода, как сделать все необходимое со всеми элементами, которые выражение XPath выбирает (в данном случае мы простоперечислите их):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match=
  "*/Dependent
      [@id = ../Election[@Status='Previous']
                                /Dependent/Dep_ID
     and
       not(@id = ../Election[@Status='Current']
                                /Dependent/Dep_ID)
      ]">

  <!-- You can do whatever processing is required here  -->
  <!-- For example:                                     -->
  Dependents that were previously elected but are not now:
  <xsl:copy-of select="."/>
 </xsl:template>

когда это преобразование применяется к вышеуказанному XML-документу, получается требуемый, правильный результат :

  Dependents that were previously elected but are not now:
  <Dependent id="100"/>

 <xsl:template match="text()"/>
</xsl:stylesheet>

ОБНОВЛЕНИЕ 2 :

ОП уточнил далее:

    <xsl:if test= 
     "parent::*/Election[(Status='Previous')]

                                 /Dependent/Dep_ID/@id=Depedent_ID"> 

  <!--  DO SOMETHING HERE if above condition is true but this is checking

только первый "ДепеЭлемент ndent .-->

Так что мой вопрос на самом деле: «В приведенном выше утверждении, как я могу проверить, равен ли Dependent_ID ЛЮБОМУ из Election / Dependent / Dep_ID / @ id родителя?

Ответ :

Это именно то условие, которое проверено.Приведенное выше условие оценивается как true(), когда существует хотя бы один

../Election[(Status='Previous')]/Dependent/Dep_ID/@id

, равный Depedent_ID (дочерний элемент Depedent_ID текущего узла).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...