2013-06-20 3 views
1

Мне нужно преобразовать XML, где правила преобразования должны применяться только для определенных элементов, а rest должен быть скопирован так же, как и он. Ниже представлены исходные и ожидаемые блоки xml.Объединить узлы XML-элементов через преобразование xslt

<Object class="Item" version="1.0" distName="A-1/B-1/Item-0"> 
    <p name="sDate">2013-02-11T00:00:00+02:00:00</p> 
    <p name="present">1</p> 
    <p name="stopD">2013-02-21T00:00:00+02:00:00</p> 
    <p name="id">CPU</p> 
</Object> 
<Object class="Period" version="1.0" distName="A-1/B-1/Item-0/Period-0"> 
    <p name="sHour">0</p> 
    <p name="sMinute">0</p> 
    <p name="interval">1</p> 
    <p name="day">0</p> 
</Object> 

к

<Object class="Items" distName="A-1/B-1/Items-0"> 
<p name="IsPresent">1</p> 
<p name="StartDate">08-11-2012</p> 
<p name="StopDate">29-11-2012</p> 
<list name="TimePeriod"> 
    <item> 
     <p name="id">1</p> 
     <p name="StartTime">00:00</p> 
     <p name="day">0</p> 
     <p name="interval">15</p> 
    </item> 
</list> 
<list name="TypeRef"> 
    <p>Diameter</p> 
</list> 

1. Над элемент предмета должно быть объединено с другим элементом объекта на основе DISTNAME, имеющей иерархию родительского ребенка. Например: А-1/B-1/Пункт-0 с A-1/B-1/Пункт-0/Период-0

  1. Mapping, как показано ниже:
    • SDATE к StartDate
    • присутствующих IsPresent
    • stopD в StopDate
    • идентификатор в TypeRef список
    • другой источник узел должен быть отображен в TimePeriod список

Может ли кто-нибудь помочь мне с этим?

+0

Для повышения эффективности в шаблоне ... делает объект с классом = «Период» всегда появляется после того, как объект с классом = «Пункт» или это может произойти до? –

+0

Это может произойти где угодно в xml. – user2363332

+0

Привет @KevinBrown, спасибо за помощь, чтобы начать с .... Просто была другая проблема, как справиться с выше, если было несколько периодов для одного элемента. Например: A-1/B-1/Item-0 имеет A-1/B-1/Item-0/Period-0 и A-1/B-1/Item-0/Period-1. Как рассмотреть оба варианта и иметь несколько списков TimePeriod по элементам? – user2363332

ответ

1

Некоторые из ваших элементов в ваших ожидаемых результатах, похоже, не соответствуют входам, но, возможно, это поможет вам добраться от точки A до точки B. Я не сделал преобразование даты здесь, и я понятия не имею, что такое TypeRef в вашем источнике.

 <xsl:template match="Object[@class='Item']"> 
      <xsl:variable name="mainobj" select="."/> 
      <xsl:variable name="distName" select="@distName"/> 
      <Object class="Items" distName="{$distName}"> 
       <p name="IsPresent"> 
        <xsl:value-of select="p[@name='present']"/> 
       </p> 
       <p name="StartDate"> 
        <xsl:value-of select="p[@name='sDate']"/> 
       </p> 
       <p name="StopDate"> 
        <xsl:value-of select="p[@name='stopD']"/> 
       </p> 
       <xsl:variable name="objperiod" select="//Object[starts-with(@distName,$distName)][not(.=$mainobj)]"/> 
       <xsl:for-each select="$objperiod"> 
       <list name="TimePeriod"> 
        <item> 
         <p name="id"> 
          <xsl:value-of select="p[@name='id']"/> 
         </p> 

         <p name="StartTime"> 
          <xsl:value-of select="concat(format-number($objperiod/p[@name='sHour'],'00'),':',format-number($objperiod/p[@name='sMinute'],'00'))"/> 
         </p> 
         <p name="day"> 
          <xsl:value-of select="$objperiod/p[@name='day']"/> 
         </p> 
         <p name="interval"> 
          <xsl:value-of select="$objperiod/p[@name='interval']"/> 
         </p> 
        </item> 
       </list> 
       </xsl:for-each> 
      </Object> 
     </xsl:template> 

Это приводит к следующему:

<Object class="Items" distName="A-1/B-1/Item-0"> 
     <p name="IsPresent">1</p> 
     <p name="StartDate">2013-02-11T00:00:00+02:00:00</p> 
     <p name="StopDate">2013-02-21T00:00:00+02:00:00</p> 
     <list name="TimePeriod"> 
      <item> 
       <p name="id">CPU</p> 
       <p name="StartTime">00:00</p> 
       <p name="day">0</p> 
       <p name="interval">1</p> 
      </item> 
     </list> 
     <list name="TimePeriod"> 
      <item> 
       <p name="id"/> 
       <p name="StartTime">00:00</p> 
       <p name="day">0</p> 
       <p name="interval">1</p> 
      </item> 
     </list> 
     <list name="TimePeriod"> 
      <item> 
       <p name="id"/> 
       <p name="StartTime">00:00</p> 
       <p name="day">0</p> 
       <p name="interval">1</p> 
      </item> 
     </list> 
    </Object> 
+0

Привет @KevinBrown, Спасибо за помощь, чтобы начать с .... Просто была другая проблема, как справиться с выше, если было несколько периодов для одного элемента. Например: A-1/B-1/Item-0 имеет A-1/B-1/Item-0/Period-0 и A-1/B-1/Item-0/Period-1. Как рассмотреть оба варианта и иметь несколько списков TimePeriod по элементам? – user2363332

+0

, если число может быть больше одного, то переменная objperiod действительно является списком узлов. переместите его над списком и используйте xsl: for-each для итерации по каждому из них –

+0

Я отредактировал решение выше, показывая это для каждого, это будет работать для 1 ... n TimePeriods. –

Смежные вопросы