我愿意:
<?xml version="1.0"?>
<NaaccrData baseDictionaryUri="http://naaccr.org/naaccrxml/naaccr-dictionary-230.xml" recordType="A" timeGenerated="2024-01-02T03:04:05.006-07:00" specificationVersion="1.6">
<Item naaccrId="recordType">A</Item>
<Item naaccrId="registryType">01</Item>
<Item naaccrId="registryId">02</Item>
<Patient>
<Item naaccrNum="1" naaccrId="p1">101</Item>
<Item naaccrNum="2" naaccrId="p2">102</Item>
<Item naaccrNum="3" naaccrId="p3">103</Item>
<Tumor>
<Item naaccrNum="11" naaccrId="t1">111</Item>
<Item naaccrNum="12" naaccrId="t2">112</Item>
</Tumor>
<Tumor>
<Item naaccrNum="11" naaccrId="t1">121</Item>
<!-- notice 122 is missing -->
</Tumor>
</Patient>
<Patient>
<Item naaccrNum="1" naaccrId="p1">201</Item>
<Item naaccrNum="2" naaccrId="p2">202</Item>
<Item naaccrNum="3" naaccrId="p3">203</Item>
<Tumor>
<Item naaccrNum="11" naaccrId="t1">211</Item>
<Item naaccrNum="12" naaccrId="t2">212</Item>
</Tumor>
</Patient>
</NaaccrData>
所需矩形 1 和所需矩形 2:
pt_id,p1,p2,p3
a,101,102,103
b,201,202,203
tumor_id,pt_id,t1,t2
x,a,111,112
y,a,121,
z,b,211,212
该 xslt 足以处理外部/患者水平,但不能处理内部/肿瘤水平。它也不分配 id。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/table">
<Root><xsl:apply-templates /></Root>
</xsl:template>
<xsl:template match="Patient|Patient/Tumor">
<pt>
<xsl:for-each select="Item">
<xsl:element name="{@naaccrId}"><xsl:value-of select = "."/></xsl:element>
</xsl:for-each>
</pt>
</xsl:template>
</xsl:stylesheet>
我正在使用 lxml Python 包, 但我对软件包和语言很灵活。 xml 文件有 100+MB。
from lxml import etree
...
# load input
dom = etree.parse(path_raw)
print(dom)
# load XSLT
transform = etree.XSLT(etree.parse(path_xslt))
print(transform)
ds = transform(dom)
print(ds)
如何生成这两个所需的矩形? xslt 是最好的方法吗?我是不是对xslt要求太多了?
编辑:为了回应@y.arazim 下面的评论,这里是一些所需的 xml。我对此很灵活,因为最终目标是将两个表上传到数据库。我认为这个输出对此很有好处,但我是这个世界的新手,并且愿意接受建议。 Json 也适合我。
<pts>
<pt>
<p1>101</p1>
<p2>102</p2>
<p3>103</p3>
<tumors>
<tumor>
<t1>111</t1>
<t2>112</t2>
</tumor>
<tumor>
<t1>121</t1>
<!-- 122 is missing -->
</tumor>
</tumor>
</pt>
<pt>
<p1>201</p1>
<p2>202</p2>
<p3>203</p3>
<tumors>
<tumor>
<t1>211</t1>
<t2>212</t2>
</tumor>
</tumors>
</pt>
</pts>
也许这样的东西适合你:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/NaaccrData">
<!-- patients -->
<xsl:text>pt_id,p1,p2,p3 </xsl:text>
<xsl:for-each select="Patient">
<xsl:value-of select="generate-id()"/>
<xsl:text>,</xsl:text>
<xsl:for-each select="Item">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:for-each>
<xsl:text> </xsl:text>
<!-- tumors -->
<xsl:text>tumor_id,pt_id,t1,t2 </xsl:text>
<xsl:for-each select="Patient">
<xsl:variable name="pt_id" select="generate-id()" />
<xsl:for-each select="Tumor">
<xsl:value-of select="generate-id()"/>
<xsl:text>,</xsl:text>
<xsl:value-of select="$pt_id"/>
<xsl:text>,</xsl:text>
<xsl:for-each select="Item">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这里假设每个患者都有相同数量的物品,肿瘤也是如此。