改变循环以组织和减少XML输出

2024-06-11 09:40:27 发布

您现在位置:Python中文网/ 问答频道 /正文

给我的XML输出如下所示:

        <lsar030><head></head><body><group1></group1><Part></part><national_stock_number_cross_reference>
            <federal_supply_classification>5310</federal_supply_classification>
            <national_item_identification_number>008805978</national_item_identification_number>
            <figure_number>700</figure_number>
            <item_number>34</item_number>
        </national_stock_number_cross_reference>
        <national_stock_number_cross_reference>
            <federal_supply_classification>5310</federal_supply_classification>
            <national_item_identification_number>008805978</national_item_identification_number>
            <figure_number>701</figure_number>
            <item_number>10</item_number>
        </national_stock_number_cross_reference>
        <national_stock_number_cross_reference>
            <federal_supply_classification>5310</federal_supply_classification>
            <national_item_identification_number>008805978</national_item_identification_number>
            <figure_number>703</figure_number>
            <item_number>9</item_number>
        </national_stock_number_cross_reference></body></lsar030>

我用xml.etree.cElementTree编写了一个基本代码来组织数据并删除重复的<federal_supply_classification>和{}信息。在

^{pr2}$

我的输出结果如下:

<nsnindxrow>
<nsn>
<fsc>5310</fsc>
<niin>00-880-5978</niin>
</nsn>
<callout assocfig="fig700" label="34">
</nsnindxrow>
<nsnindxrow>
<nsn>
<fsc></fsc>
<niin></niin>
</nsn>
<callout assocfig="fig701" label="10">
</nsnindxrow>
<nsnindxrow>
<nsn>
<fsc></fsc>
<niin></niin>
</nsn>
<callout assocfig="fig703" label="9">
</nsnindxrow>

当我需要以这样的输出结束时。在

<nsnindxrow>
<nsn>
<fsc>5310</fsc>
<niin>00-880-5978</niin>
</nsn>
<callout assocfig="fig700" label="34">
<callout assocfig="fig701" label="10">
<callout assocfig="fig703" label="9">
</nsnindxrow>

有没有一种简单的方法可以将find和remove添加到代码中,还是需要调整循环语句?怎么办?在


Tags: numberstockitemfigurereferenceclassificationcrossnational
2条回答

请原谅我建议另一种方法,但请考虑使用XSLT解决方案,因为您需要的是典型的Muenchian Method,涉及对<federal_supply_classification>和{}配对进行分组。{Stylesheet}是一种特殊的XML文档格式,专门用来转换XML文档。在

Python的lxml模块可以运行XSLT1.0脚本,也可以在命令行调用外部处理器,如Saxon/Xalan或PowerShell/Bash。在这种方法中,您可以避免任何通用循环或条件逻辑,甚至避免元素的字符串连接。最后,XSLT是一个格式良好的XML文件,因此可以像任何其他XML文档一样从文件或字符串中解析。在

下面的示例将您发布的XML示例包装在根标记中:<root>...</root>。将XSLT的第一个模板中的root改为实际的XML根。在

XSLT脚本(另存为.xsl,将在下面引用)

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

 <xsl:key name="numkey" match="national_stock_number_cross_reference"
          use="concat(federal_supply_classification, national_item_identification_number)"/>

  <xsl:template match="root">    
      <xsl:apply-templates select="national_stock_number_cross_reference[generate-id() =
           generate-id(key('numkey', concat(federal_supply_classification, national_item_identification_number))[1])]"/>    
  </xsl:template>

 <xsl:template match="national_stock_number_cross_reference">
  <nsnindxrow>
    <nsn> 
      <fsc><xsl:value-of select="federal_supply_classification"/></fsc>
      <niin><xsl:value-of select="national_item_identification_number"/></niin>
    </nsn>
    <xsl:for-each select="key('numkey', concat(federal_supply_classification, national_item_identification_number))">
      <callout>
        <xsl:attribute name="assocfig"><xsl:value-of select="concat('fig', figure_number)"/></xsl:attribute>
        <xsl:attribute name="label"><xsl:value-of select="item_number"/></xsl:attribute>
      </callout>
    </xsl:for-each>
  </nsnindxrow>  
 </xsl:template>

</xsl:stylesheet>

Python脚本

^{pr2}$

输出

<?xml version='1.0' encoding='UTF-8'?>
<nsnindxrow>
  <nsn>
    <fsc>5310</fsc>
    <niin>008805978</niin>
  </nsn>
  <callout assocfig="fig700" label="34"/>
  <callout assocfig="fig701" label="10"/>
  <callout assocfig="fig703" label="9"/>
</nsnindxrow>

每次循环national_stock_number_cross_reference项(第三个for循环)时,都会创建一个新的<nsnindxrow>标记:

for national_stock_number_cross_reference in body.findall('./' + junk + 'national_stock_number_cross_reference'):

第一次通过for循环时,它创建了<nsn>标记,因为repeat为false。然后repeat被切换到true,因此它在下次通过时放置一个空标记。它对您拥有的所有不同的federal_supply_classification项都这样做,在本例中是3。在

您需要在这个循环之前移动<nsn>标记创建过程,以避免每次都重新创建它。在

相关问题 更多 >