将xml父元素和属性内容复制到子元素

时间:2018-04-03 16:28:53

标签: xml xslt attributes elements

无法获得已发布的答案 - 以下示例更为真实,因此可能有助于更好地解释我的目标:

目前的数据如下:

<LabTest_ID>0001</LabTest_ID>

<FullName>Cluster of differentiation 19+, lambda+ count</FullName>

<SnomedCT conceptId="799711000000109" preferredTerm="Count of cells positive for both CD19 and lambda" />

<CollectedSpecimen id="blood" type="Blood" snomedCTConceptId="119297000">
    <CollectionMethod id="L0000" name="Arterial" snomedCTConceptId="122552005" />
    <CollectionMethod id="L0050" name="Venous" snomedCTConceptId="122555007" />
</CollectedSpecimen>

<CollectedSpecimen id="bonemarrow" type="Bone marrow" snomedCTConceptId="119359002">
    <CollectionMethod id="L0001" name="Aspiration" snomedCTConceptId="801861000000103" />
</CollectedSpecimen>

我想从此转换CollectionMethod的输出:

<CollectionMethod id="L0000" name="Arterial" snomedCTConceptId="122552005" />

到此:

<CollectionMethod LabTest_ID = "0001" type = "Blood" id="L0000" name="Arterial" snomedCTConceptId="122552005" />

也就是说我想将LabTest的'LabTest_ID'和CollectedSpecimen的'type'作为附加属性添加到CollectedMethod。

我对XML很新,并尝试了以下几乎可以工作的代码,但只在第一次出现的CollectionMethod中为每个CollectedSpecimen输出LabTest_ID而不是每个。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <dataroot>
            <xsl:apply-templates select="@*|node()"/>
        </dataroot>
    </xsl:template>

    <xsl:template match="CollectionMethod/@*">
        <xsl:element name="{name()}">
        <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="CollectedSpecimen/@type" />
        <xsl:template match="CollectedSpecimen[@type]/*[1]">
            <xsl:copy>
                <xsl:apply-templates select="@*" />
                    <CollectedSpecimen-type>
                        <xsl:value-of select="../@type" />
                    </CollectedSpecimen-type>
                <xsl:apply-templates select="node()"/>
            </xsl:copy>
    </xsl:template>

        <xsl:template match="CollectionMethod">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:template>

    <xsl:template match="CollectionMethod">
        <CollectionMethod>
            <LabTest_ID><xsl:value-of select="../../LabTest_ID"/></LabTest_ID>
            <xsl:apply-templates select="@*|node()"/>
        </CollectionMethod>
    </xsl:template>

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

以下模板将新属性添加到XML。 标识模板复制除Grandchild元素之外的所有节点,这些元素由更具体的模板处理。

<!-- identity template -->
<xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
 </xsl:template>  

<xsl:template match="Grandchild">
    <xsl:copy>
        <xsl:copy-of select="@*" />              <!-- copies all existing attributes -->
        <xsl:attribute name="Childid">           <!-- Adds the additional Childid attribute -->
          <xsl:value-of  select="../@id" />
        </xsl:attribute>
        <xsl:attribute name="Parentid">          <!-- Adds the additional Parrentid attribute -->
          <xsl:value-of  select="../../Parent_ID" />
        </xsl:attribute>
    </xsl:copy>
</xsl:template>