微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用python修改xml文件时如何注册多个默认命名空间?

如何解决使用python修改xml文件时如何注册多个默认命名空间?

在这里浏览了许多命名空间文档,但只能与其中的一些略有关联。在我的文档中,我有 3 个认值,只有一个冒号样式的 xmlns,例如:

xmlns="someurlNo1"
xmlns:spatial="someurlNo2"
xmlns="someurlNo3"
xmlns="someurlNo4"

从我读到的内容来看,似乎我有 3 个认值(如果我解释错了,请纠正我),但是当我修改我的基本 xml 然后编写我的新 xml 时,我只能避免出现前两个,ns0 和 ns1,不会通过注释掉后两个来显示,这使得最后两个认值的其他部分都标有“ns2”和“ns3”,即使我全部注册如下:

ET.register_namespace('',"someurlNo0") #ns0
ET.register_namespace('spatial',"someurlNo1") #ns1
#ET.register_namespace('',"someurlNo2") #ns2
#ET.register_namespace('',"someurlNo3") #ns3

有谁知道如何正确注册最后两个认命名空间?当我不注释掉最后两个时,ns0 和 ns2 出现在它们应该出现的地方,虽然所有 ns3 都消失了,但认值不再等于“someurlNo3”。 这个答案:https://stackoverflow.com/a/43530940 到目前为止对我来说是最有帮助的解释,说明可能有多个认值向下传播(我认为这对我的文档是正确的),但我仍然不确定如何正确注册它们.任何想法将不胜感激!

这是我的 xml 顶部的样子,包括所有 4 个命名空间。我宁愿让你不要看到所有 3k 行,但如果需要,我可以分享更多:

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version1/core" level="3" spatial:required="true" version="1" xmlns:spatial="http://www.sbml.org/sbml/level3/version1/spatial/version1">
  <notes>
    <body xmlns="http://www.w3.org/1999/xhtml">
     <p>Exported by VCell 7.3</p>
  </body>
  </notes>
  <model areaUnits="um2" extentUnits="molecules" id="_zero_6_29_21_Phase1_cellularConcAgain_Spatial" lengthUnits="um" name="06_29_21_Phase1_cellularConcAgain_Spatial" substanceUnits="molecules" timeUnits="s" volumeUnits="um3">
    <spatial:geometry xmlns:spatial="http://www.sbml.org/sbml/level3/version1/spatial/version1" id="vcell" spatial:coordinateSystem="cartesian" spatial:id="vcell">
      <spatial:listofCoordinateComponents>
        <spatial:coordinateComponent id="x" spatial:id="x" spatial:type="cartesianX" spatial:unit="um">
          <spatial:boundaryMin id="Xmin" spatial:id="Xmin" spatial:value="0.0"/>
          <spatial:boundaryMax id="Xmax" spatial:id="Xmax" spatial:value="1.6"/>
        </spatial:coordinateComponent>
        <spatial:coordinateComponent id="y" spatial:id="y" spatial:type="cartesianY" spatial:unit="um">
          <spatial:boundaryMin id="Ymin" spatial:id="Ymin" spatial:value="0.0"/>
          <spatial:boundaryMax id="Ymax" spatial:id="Ymax" spatial:value="3.5"/>
        </spatial:coordinateComponent>
      </spatial:listofCoordinateComponents>
      <spatial:listofDomains>
        <spatial:domain id="chr0" spatial:domainType="domainType_chr" spatial:id="chr0">
          <spatial:listofInteriorPoints>
            <spatial:interiorPoint spatial:coord1="0.0" spatial:coord2="0.0" spatial:coord3="5.0"/>
          </spatial:listofInteriorPoints>
        </spatial:domain>
      </spatial:listofDomains>
      <spatial:listofDomainTypes>
        <spatial:domainType id="domainType_chr" spatial:id="domainType_chr" spatial:spatialDimensions="3"/>
      </spatial:listofDomainTypes>
      <spatial:listofGeometryDeFinitions>
        <spatial:analyticGeometry id="Analytic_Geometry1640227629" spatial:id="Analytic_Geometry1640227629" spatial:isActive="true">
          <spatial:listofAnalyticVolumes>
            <spatial:analyticVolume spatial:domainType="domainType_chr" spatial:functionType="layered" spatial:id="chr" spatial:ordinal="0">
              <math xmlns="http://www.w3.org/1998/Math/MathML">              
                <apply>
                  <neq/>
                  <cn> 0 </cn>
                  <cn> 1 </cn>
                </apply>
              </math>

解决方法

你误解了命名空间。命名空间是“默认”不是该命名空间的属性,而是该位置中 XML 的属性。

不要分心。为您将要使用的所有命名空间 URI 提供一个前缀,完成。

ns = {
    'a': 'someurlNo0','b': 'someurlNo1','c': 'someurlNo2','d': 'someurlNo3','e': 'someurlNo3',# same URI as above,perfectly legal
}

tree = ET.parse('path/to.xml')

tree.findall("./a:node/b:node/c:node/d:node/e:node",namespaces=ns)

它甚至不需要与您的 XML 中的前缀相同。事实上,避免这种情况。为命名空间 URI 提供前缀使阅读代码变得容易。最后重要的是命名空间 URI,前缀是短暂的。

只要您代码中的前缀解析为目标节点的实际命名空间 URI,您就很好。命名空间是否在 XML 中的特定位置是默认的并不重要。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。