2010-10-07 4 views
1

У меня есть следующий XML:XSLT: Изменение значения атрибута на основе собрата значения атрибута

<?xml version="1.0" encoding="UTF-8"?> 
<ODM FileOID="some oid" Description="some desc" CreationDateTime="2010-10-06T22:35:00-06:00" FileType="Snapshot" > 
    <Study OID="S_TEST"> 
     <GlobalVariables> 
      <StudyName>Study_Name</StudyName> 
      <StudyDescription> 
       Some study description 
      </StudyDescription> 
      <ProtocolName>Some protocol name</ProtocolName> 
     </GlobalVariables> 
     <MetaDataVersion OID="v1.0.0" Name="MetaDataVersion_v1.0.0"> 
      <Protocol> 
       <StudyEventRef StudyEventOID="SE01" OrderNumber="36" Mandatory="Yes"/> 
       <StudyEventRef StudyEventOID="SE02" OrderNumber="37" Mandatory="Yes"/> 
      </Protocol> 
      <StudyEventDef OID="SE01" Name="Some name 01" Repeating="No" Type="Scheduled"> 
       <FormRef FormOID="F01" Mandatory="Yes"/> 
       <FormRef FormOID="F02" Mandatory="Yes"/> 
      </StudyEventDef> 
      <StudyEventDef OID="SE02" Name="Some name 02" Repeating="No" Type="Scheduled"> 
       <FormRef FormOID="F01" Mandatory="Yes"/> 
       <FormRef FormOID="F02" Mandatory="Yes"/> 
      </StudyEventDef> 
      <FormDef OID="F01" Name="Some form name 01" Repeating="No"> 
       <ItemGroupRef ItemGroupOID="IG01" Mandatory="Yes"/> 
      </FormDef> 
      <FormDef OID="F02" Name="Some form name 02" Repeating="No"> 
       <ItemGroupRef ItemGroupOID="IG02" Mandatory="Yes"/> 
       <ItemGroupRef ItemGroupOID="IG03" Mandatory="No"/> 
      </FormDef> 
      <ItemGroupDef OID="IG01" Name="Ungrouped" Repeating="No" SASDatasetName="UNGROUPE"> 
       <ItemRef ItemOID="I01" OrderNumber="1" Mandatory="Yes"/> 
       <ItemRef ItemOID="I02" OrderNumber="2" Mandatory="Yes"/> 
       <ItemRef ItemOID="I03" OrderNumber="3" Mandatory="Yes"/> 
      </ItemGroupDef> 
      <ItemGroupDef OID="IG02" Name="Reasons2" Repeating="Yes" SASDatasetName="REASONS2"> 
       <ItemRef ItemOID="I04" OrderNumber="1" Mandatory="No"/> 
      </ItemGroupDef> 
      <ItemGroupDef OID="IG03" Name="Ungrouped" Repeating="No" SASDatasetName="UNGRO002"> 
       <ItemRef ItemOID="I05" OrderNumber="1" Mandatory="Yes"/> 
       <ItemRef ItemOID="I06" OrderNumber="2" Mandatory="Yes"/> 
      </ItemGroupDef> 
     </MetaDataVersion> 
    </Study> 
</ODM> 

То, что я хочу сделать это для каждого <ItemGroupDef> элемента с «Именем» атрибут равно «разгруппированы», изменение это значение атрибута «XXX-Ungrouped», где XXX - это значение атрибута OID для элемента <FormDef>, у которого есть дочерний элемент <ItemGroupRef> с атрибутом ItemGroupOID, равным атрибуту OID элемента ItemGroupDef. Все остальные атрибуты и все дочерние элементы этого элемента должны оставаться неизменными.

Например, для приведенного выше <ItemGroupDef OID="IG01">, атрибут Name должен быть изменен с «Негруппированные» до «F01-разгруппирована», так как это OID, IG01, выступает в качестве дочернего элемента <FormDef OID="F01">. Гарантируется, что любое значение OID ItemGroupDef появляется как дочерний элемент только одного элемента <FormDef>.

Преобразование должно действовать на <ItemGroupDef> элементов с атрибутом атрибута Name только для «Ungrouped». Все элементы <ItemGroupDef> с атрибутом Name, отличным от «Ungrouped», и все остальные элементы в XML-файле должны оставаться неизменными.

ответ

1

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="kOIDbyItemGroup" match="FormDef/@OID" 
      use="../ItemGroupRef/@ItemGroupOID"/> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="ItemGroupDef/@Name[.='Ungrouped']"> 
     <xsl:attribute name="Name"> 
      <xsl:value-of select="concat(key('kOIDbyItemGroup',../@OID), 
             '-',.)"/> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

Выход:

<ODM FileOID="some oid" Description="some desc" CreationDateTime="2010-10-06T22:35:00-06:00" FileType="Snapshot"> 
    <Study OID="S_TEST"> 
     <GlobalVariables> 
      <StudyName>Study_Name</StudyName> 
      <StudyDescription> 
       Some study description 
      </StudyDescription> 
      <ProtocolName>Some protocol name</ProtocolName> 
     </GlobalVariables> 
     <MetaDataVersion OID="v1.0.0" Name="MetaDataVersion_v1.0.0"> 
      <Protocol> 
       <StudyEventRef StudyEventOID="SE01" OrderNumber="36" Mandatory="Yes"></StudyEventRef> 
       <StudyEventRef StudyEventOID="SE02" OrderNumber="37" Mandatory="Yes"></StudyEventRef> 
      </Protocol> 
      <StudyEventDef OID="SE01" Name="Some name 01" Repeating="No" Type="Scheduled"> 
       <FormRef FormOID="F01" Mandatory="Yes"></FormRef> 
       <FormRef FormOID="F02" Mandatory="Yes"></FormRef> 
      </StudyEventDef> 
      <StudyEventDef OID="SE02" Name="Some name 02" Repeating="No" Type="Scheduled"> 
       <FormRef FormOID="F01" Mandatory="Yes"></FormRef> 
       <FormRef FormOID="F02" Mandatory="Yes"></FormRef> 
      </StudyEventDef> 
      <FormDef OID="F01" Name="Some form name 01" Repeating="No"> 
       <ItemGroupRef ItemGroupOID="IG01" Mandatory="Yes"></ItemGroupRef> 
      </FormDef> 
      <FormDef OID="F02" Name="Some form name 02" Repeating="No"> 
       <ItemGroupRef ItemGroupOID="IG02" Mandatory="Yes"></ItemGroupRef> 
       <ItemGroupRef ItemGroupOID="IG03" Mandatory="No"></ItemGroupRef> 
      </FormDef> 
      <ItemGroupDef OID="IG01" Name="F01-Ungrouped" Repeating="No" SASDatasetName="UNGROUPE"> 
       <ItemRef ItemOID="I01" OrderNumber="1" Mandatory="Yes"></ItemRef> 
       <ItemRef ItemOID="I02" OrderNumber="2" Mandatory="Yes"></ItemRef> 
       <ItemRef ItemOID="I03" OrderNumber="3" Mandatory="Yes"></ItemRef> 
      </ItemGroupDef> 
      <ItemGroupDef OID="IG02" Name="Reasons2" Repeating="Yes" SASDatasetName="REASONS2"> 
       <ItemRef ItemOID="I04" OrderNumber="1" Mandatory="No"></ItemRef> 
      </ItemGroupDef> 
      <ItemGroupDef OID="IG03" Name="F02-Ungrouped" Repeating="No" SASDatasetName="UNGRO002"> 
       <ItemRef ItemOID="I05" OrderNumber="1" Mandatory="Yes"></ItemRef> 
       <ItemRef ItemOID="I06" OrderNumber="2" Mandatory="Yes"></ItemRef> 
      </ItemGroupDef> 
     </MetaDataVersion> 
    </Study> 
</ODM> 

Примечание: Перезапись правило Indentity. Ключи для перекрестных ссылок. Устанавливают ключи узла.

От Комментарии:

один вопрос: в XSLT выводит элементы как этот <FormRef FormOID="F01" Mandatory="Yes"></FormRef> когда оригинальные элементы был <FormRef FormOID="F01" Mandatory="Yes"/>. Оба из них соответствуют стандартам XML, , но есть ли способ рассказать XSLT об выходных элементах в том же точном формате ?

Может быть (Испытано с MSXSL, Altova, Saxon, Oracle, XQSharp)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="kOIDbyItemGroup" match="FormDef/@OID" 
       use="../ItemGroupRef/@ItemGroupOID"/> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="*[not(node())]"> 
     <xsl:element name="{name()}"> 
      <xsl:apply-templates select="@*"/> 
     </xsl:element> 
    </xsl:template> 
    <xsl:template match="ItemGroupDef/@Name[.='Ungrouped']"> 
     <xsl:attribute name="Name"> 
      <xsl:value-of select="concat(key('kOIDbyItemGroup',../@OID), 
              '-',.)"/> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

Выход:

<ODM FileOID="some oid" Description="some desc" CreationDateTime="2010-10-06T22:35:00-06:00" FileType="Snapshot"> 
    <Study OID="S_TEST"> 
     <GlobalVariables> 
      <StudyName>Study_Name</StudyName> 
      <StudyDescription> 
       Some study description 
      </StudyDescription> 
      <ProtocolName>Some protocol name</ProtocolName> 
     </GlobalVariables> 
     <MetaDataVersion OID="v1.0.0" Name="MetaDataVersion_v1.0.0"> 
      <Protocol> 
       <StudyEventRef StudyEventOID="SE01" OrderNumber="36" Mandatory="Yes"/> 
       <StudyEventRef StudyEventOID="SE02" OrderNumber="37" Mandatory="Yes"/> 
      </Protocol> 
      <StudyEventDef OID="SE01" Name="Some name 01" Repeating="No" Type="Scheduled"> 
       <FormRef FormOID="F01" Mandatory="Yes"/> 
       <FormRef FormOID="F02" Mandatory="Yes"/> 
      </StudyEventDef> 
      <StudyEventDef OID="SE02" Name="Some name 02" Repeating="No" Type="Scheduled"> 
       <FormRef FormOID="F01" Mandatory="Yes"/> 
       <FormRef FormOID="F02" Mandatory="Yes"/> 
      </StudyEventDef> 
      <FormDef OID="F01" Name="Some form name 01" Repeating="No"> 
       <ItemGroupRef ItemGroupOID="IG01" Mandatory="Yes"/> 
      </FormDef> 
      <FormDef OID="F02" Name="Some form name 02" Repeating="No"> 
       <ItemGroupRef ItemGroupOID="IG02" Mandatory="Yes"/> 
       <ItemGroupRef ItemGroupOID="IG03" Mandatory="No"/> 
      </FormDef> 
      <ItemGroupDef OID="IG01" Name="F01-Ungrouped" Repeating="No" SASDatasetName="UNGROUPE"> 
       <ItemRef ItemOID="I01" OrderNumber="1" Mandatory="Yes"/> 
       <ItemRef ItemOID="I02" OrderNumber="2" Mandatory="Yes"/> 
       <ItemRef ItemOID="I03" OrderNumber="3" Mandatory="Yes"/> 
      </ItemGroupDef> 
      <ItemGroupDef OID="IG02" Name="Reasons2" Repeating="Yes" SASDatasetName="REASONS2"> 
       <ItemRef ItemOID="I04" OrderNumber="1" Mandatory="No"/> 
      </ItemGroupDef> 
      <ItemGroupDef OID="IG03" Name="F02-Ungrouped" Repeating="No" SASDatasetName="UNGRO002"> 
       <ItemRef ItemOID="I05" OrderNumber="1" Mandatory="Yes"/> 
       <ItemRef ItemOID="I06" OrderNumber="2" Mandatory="Yes"/> 
      </ItemGroupDef> 
     </MetaDataVersion> 
    </Study> 
</ODM> 
+0

Спасибо вам большое за решение. – Mihai

+0

Один вопрос: XSLT выводит такие элементы , когда исходные элементы были . Оба они верны по стандартам XML, но есть ли способ рассказать XSLT о выходе элементов в том же точном формате? – Mihai

+0

@Mihai: Потому что (как вы писали) оба формата пустого элемента семантически одинаковы, трудно сказать, что для этого кросс-процессорное решение. Посмотрите на мою интимную версию. – 2010-10-08 20:43:13

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