将 xml 拆分为表并添加 ids

问题描述 投票:0回答:1

我愿意:

  1. 使用 xslt 将嵌套的 xml 转换为两个表格/矩形。 (我已将表格编写为 csv,但如果它们是非嵌套 xml 就可以了。)
  2. 在两个级别(例如,患者和肿瘤)任意分配 ID。 (我使用了字母,因此它们在此示例中脱颖而出,但连续数字可能更可取。)
<?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>
xml xslt
1个回答
0
投票

也许这样的东西适合你:

<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&#10;</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>&#10;</xsl:text>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    
    <!-- tumors -->
    <xsl:text>tumor_id,pt_id,t1,t2&#10;</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>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

这里假设每个患者都有相同数量的物品,肿瘤也是如此。

© www.soinside.com 2019 - 2024. All rights reserved.