2010-10-07 102 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是<FormDef>元素的OID屬性的值,該元素具有子項ItemGroupOID屬性等於ItemGroupDef元素的OID屬性。該元素的所有其他屬性和所有子元素都應保持不變。

例如,對於上面的<ItemGroupDef OID="IG01">,由於此OID IG01顯示爲<FormDef OID="F01">元素的子項,因此應將Name屬性從「未分組」更改爲「F01-未分組」。可以確保任何ItemGroupDef OID值都只顯示爲一個<FormDef>元素的子元素。

該轉換應該只對名稱屬性值爲「未分組」的<ItemGroupDef>元素起作用。 Name屬性爲「Ungrouped」以外的所有<ItemGroupDef>元素以及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公司,薩克森,甲骨文,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 2010-10-08 20:29:58

+0

一個問題:當原始元素是時,XSLT輸出像這樣的元素。這兩種方法在XML標準中都是正確的,但是有沒有辦法讓XSLT以相同的格式輸出元素? – Mihai 2010-10-08 20:30:31

+0

@Mihai:因爲(如你所寫)空元素的格式在語義上是相同的,所以很難說出什麼是交叉處理器解決方案。看看我的包裝版。 – 2010-10-08 20:43:13