将XML父元素及属性内容复制到子元素(原方案无效附实例)
解决方案:用XSLT将父元素属性复制到子元素
首先,我把你给出的XML片段补全成完整可测试的示例,方便明确需求:
<LabTest> <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="L001" name="Venipuncture" /> <SpecimenVolume value="5" unit="mL" /> </CollectedSpecimen> </LabTest>
你的需求应该是把<CollectedSpecimen>的属性批量复制到它的子元素中,之前的方案没生效大概率是没处理好XML节点的复制逻辑,试试用XSLT来实现——这是处理XML结构修改的标准工具:
实现代码(XSLT 1.0)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 默认模板:原样复制所有节点和属性,保证其他元素不受影响 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 专门匹配CollectedSpecimen的子元素,添加父元素的属性 --> <xsl:template match="CollectedSpecimen/*"> <xsl:copy> <!-- 先复制父元素的所有属性 --> <xsl:apply-templates select="../@*"/> <!-- 再保留当前子元素自己的属性和内容 --> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
转换后的结果
用上述XSLT处理原XML后,子元素会带上父元素的所有属性:
<LabTest> <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="blood" type="Blood" snomedCTConceptId="119297000" id="L001" name="Venipuncture" /> <SpecimenVolume id="blood" type="Blood" snomedCTConceptId="119297000" value="5" unit="mL" /> </CollectedSpecimen> </LabTest>
调整方案(按需修改)
- 如果不想复制父元素的所有属性,只复制特定几个(比如
type和snomedCTConceptId),把../@*改成../@type | ../@snomedCTConceptId即可。 - 如果子元素和父元素有重名属性(比如示例里的
id),虽然XML允许重复属性,但如果想避免冲突,可以给父属性加前缀区分,修改模板如下:<xsl:template match="CollectedSpecimen/*"> <xsl:copy> <!-- 给父属性加前缀区分 --> <xsl:attribute name="parent-id"><xsl:value-of select="../@id"/></xsl:attribute> <xsl:attribute name="parent-type"><xsl:value-of select="../@type"/></xsl:attribute> <xsl:attribute name="parent-snomedCTConceptId"><xsl:value-of select="../@snomedCTConceptId"/></xsl:attribute> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template>
你可以用任何支持XSLT的工具(比如Saxon、XMLSpy,或者在线XSLT转换器)测试这个方案,应该能解决你的问题。
内容的提问来源于stack exchange,提问作者renc
相关产品推荐
相关产品推荐

