使用XSLT将儿童节点重复为CSV/ TSV的一行



如果我有以下XML文件

<AnnotationSet Name="Bio">
<Annotation Id="6164" Type="Health_Care_Related_Organization" StartNode="0" EndNode="6">
<Feature>
  <Name className="java.lang.String">VOCABS</Name>
  <Value className="java.lang.String">NCI</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">Negation</Name>
  <Value className="java.lang.String">Affirmed</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">inst_full</Name>
  <Value className="java.lang.String">http://linkedlifedata.com/resource/umls/id/C0002424</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">Experiencer</Name>
  <Value className="java.lang.String">Patient</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">PREF</Name>
  <Value className="java.lang.String">Clinic</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">inst</Name>
  <Value className="java.lang.String">C0002424</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">STY</Name>
  <Value className="java.lang.String">Health Care Related Organization</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">TUI</Name>
  <Value className="java.lang.String">T093</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">language</Name>
  <Value className="java.lang.String"></Value>
</Feature>
<Feature>
  <Name className="java.lang.String">Temporality</Name>
  <Value className="java.lang.String">Recent</Value>
</Feature>
<Feature>
  <Name className="java.lang.String">tui_full</Name>
  <Value className="java.lang.String">http://linkedlifedata.com/resource/semanticnetwork/id/T093</Value>
</Feature>
</Annotation>
</AnnotationSet>

我希望能够将每个子节点<Feature>和一个列标头的Name元素以及<Value>元素作为值,并放入CSV或TSV中。我也希望StartNodeEndNode作为<Annotation>节点的列。

看起来像:

StartNode    EndNode    VOCABS    Negation    ....
---------    -------    ------    --------    ----
0            6          NCI       Affirmed    ....

我只熟悉编写每个节点,即<Feature>包含每一行的每一列。在这里,每一行都包含在<Annotation>中,并且很难拉出我的需求。

我尝试编写以下XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" encoding="utf-8"/>
<xsl:template match="/">
    <xsl:text>Name, Value &#10;</xsl:text>
    <xsl:for-each select="AnnotationSet/Annotation/Feature">
        <xsl:value-of select="concat(Name,',',Value)"/>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

,但是在http://www.freeformatter.com/xsl-transformer.html上进行测试时无法运行

有人有任何想法吗?

测试XSLT后,我希望在Python中这样做,其中有以下Python脚本:

#!/usr/bin/env python
import lxml.etree as ET
import sys
import os
dom = ET.parse('gatetest.xml')
xslt = ET.parse('gate.xsl')
transform = ET.XSLT(xslt)
newdom = transform(dom)
print(ET.tostring(newdom, pretty_print=True))

您尝试连接NameValue的尝试是没有意义的,因为您需要它们在另一个以下,而不是另一个以外。更不用说您只需要每个名称一次(在第一行中)。

而不是这样尝试:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/AnnotationSet">
    <xsl:text>StartNode&#9;EndNode</xsl:text>
    <xsl:for-each select="Annotation[1]/Feature">
        <xsl:text>&#9;</xsl:text>
        <xsl:value-of select="Name"/>
    </xsl:for-each>
    <xsl:for-each select="Annotation">
        <xsl:text>&#10;</xsl:text>
        <xsl:value-of select="@StartNode" />
        <xsl:text>&#9;</xsl:text>
        <xsl:value-of select="@EndNode" />
        <xsl:for-each select="Feature">
            <xsl:text>&#9;</xsl:text>
            <xsl:value-of select="Value"/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

您的示例中的结果将看起来像这样(很难正确地显示正确对齐的选项卡分隔值):

StartNode   EndNode VOCABS  Negation    inst_full   Experiencer PREF    inst    STY TUI language    Temporality tui_full
0   6   NCI Affirmed    http://linkedlifedata.com/resource/umls/id/C0002424 Patient Clinic  C0002424    Health Care Related Organization    T093        Recent  http://linkedlifedata.com/resource/semanticnetwork/id/T093

最新更新