XSLT: изменить значение атрибута на основе значения атрибута родного брата - PullRequest
1 голос
/ 08 октября 2010

У меня есть следующий 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>

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

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

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

1 Ответ

1 голос
/ 08 октября 2010

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

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...