2010-10-07 108 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