【问题标题】:Change XML grandchild value if child value is equal to another value如果子值等于另一个值,则更改 XML 孙值
【发布时间】:2018-07-10 19:20:47
【问题描述】:

我需要更正数百个 XML 文件。

假设文件是​​这种格式:

<?xml version="1.0" encoding="UTF-8"?>
<MyData xmlns="urn:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso">
  <Hdr>
    <AppHdr xmlns="urn:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso">
      <St>A</St>
      <To>Z</To>
  </Hdr>
  <Data>
    <Document xmlns="urn:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso">
      <CountryReport>
        <RptHdr>
            <RpDtls>
                <Dt>2018-07-10</Dt>
          </RpDtls>
        </RptHdr>
        <Country>
          <Id>PT</Id>
          <FullNm>Portugal</FullNm>>
          <Bd>
            <Tp>US</Tp>
          </Bd>
        </Country>
        <Country>
          <Id>ESP</Id>
          <FullNm>Spain</FullNm>>
          <Bd>
            <Tp>EUR</Tp>
          </Bd>
        </Country>
      </CountryReport>
    </Document>
  </Data>
</MyData>

我需要做的替换如下:

  • 如果 Country ID 是 PT,我需要将 Bd/Tp 替换为“EUR”。

我尝试了使用 python 使用 sed、xmllint 和 ElementTrees 的不同方法,但没有成功。

我可能使用了错误的 xpath,但很遗憾我无法弄清楚。

你能帮忙吗?

【问题讨论】:

  • 您好,欢迎您。也许尝试发布您尝试过的内容以及您怀疑有“错误xpath”的地方。当人们看到迄今为止所付出的努力并且可以帮助解决您遇到的特定问题时,他们通常会更乐意提供帮助。

标签: python xml parsing element elementtree


【解决方案1】:

实现目标的最简单方法是使用 XSLT 处理器。例如,使用调用 Linux 程序 xsltproc 或 Windows/Linux 程序 saxon 的脚本。

因为您的元素位于命名空间中,所以您必须为您的元素定义它。例如,将xmlns:ui="urn:iso" 添加到您的xsl:stylesheet 元素中,然后将以下模板与身份模板结合使用:

<xsl:template match="ui:Country[ui:Id='PT']/ui:Bd/ui:Tp">
  <xsl:element name="Tp" namespace="{namespace-uri()}">EUR</xsl:element>
</xsl:template>

XSLT-1.0的身份模板是:

<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*" />
  </xsl:copy>
</xsl:template> 

对于 XSLT-3.0,您可以改用以下指令:

<xsl:mode on-no-match="shallow-copy" />

因此,用于转换所有 XML 文件的完整 XSLT-1.0 文件可能如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ui="urn:iso">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

  <!-- identity template -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
   </xsl:template>  

  <xsl:template match="ui:Country[ui:Id='PT']/ui:Bd/ui:Tp">
    <xsl:element name="Tp" namespace="{namespace-uri()}">EUR</xsl:element>
  </xsl:template>

</xsl:stylesheet>

xsltproc bash 命令可能看起来像

for file in *; do xsltproc transform.xslt $file > $file.NEW; done; 

【讨论】:

  • 或者您可以使用 Python 的 lxml library 运行 XSLT 1.0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多