XSLT:根据兄弟属性值修改属性值

时间:2010-10-07 20:35:28

标签: xslt

我有以下XML:

<?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>

我想要做的是,对于“Name”属性等于“Ungrouped”的每个<ItemGroupDef>元素,将此属性值更改为“XXX-Ungrouped”,其中XXX是OID属性的值对于有{child} <FormDef>&gt;的<ItemGroupRef元素ItemGroupOID属性等于ItemGroupDef元素的OID属性。所有其他属性和该元素的所有子元素都应保持不变。

例如,对于上面的<ItemGroupDef OID="IG01">,Name属性应该从“Ungrouped”更改为“F01-Ungrouped”,因为此OID IG01显示为<FormDef OID="F01">元素的子元素。保证任何ItemGroupDef OID值仅显示为一个<FormDef>元素的子项。

转换应该仅对<ItemGroupDef>元素起作用,并且Name属性值为“Ungrouped”。 Name属性不是“Ungrouped”的所有<ItemGroupDef>元素和XML文件中的所有其他元素都应保持不变。

1 个答案:

答案 0 :(得分: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>

注意:覆盖缩进规则。用于交叉参考的键。节点集键。

来自评论:

  

一个问题: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>