【问题标题】:lxml finding last optional XML Elementlxml 查找最后一个可选 XML 元素
【发布时间】:2021-05-08 02:59:15
【问题描述】:

我正在使用 LXML 来处理现有的 XML 块,我想要:

  1. 如果标签存在则更改元素值
  2. 如果不存在,则创建元素

(2)的问题是:将元素插入块内的正确位置,其中大部分元素是可选的。注意:有一个定义结构的 XSD。

例如,我想插入<d>,如果存在,它将出现在<c>之后,否则在<b>之后,如果存在,否则在<a>之后

<OuterElement>
    <a>value of a</a> --- Optional
    <b>value of b</b> --- Optional
    <c>value of c</c> --- Optional
    <d>value of d</d>
    <e>value of e</e> --- Optional
</OuterElement>

实现这一目标的最简洁/最简单的方法是什么?目前我正在使用 XPath 表达式循环元素 - 这感觉相当 hacky。

【问题讨论】:

  • 那么架构看起来究竟如何?
  • 不幸的是,我无法将确切的架构放在这里,但是上面 OuterElement 示例中的每个元素都有 minOccurs=0,因此使其成为可选的。我不确定如何轻松计算出最后一个可选元素,以便将 &lt;d&gt; 放置在正确的位置
  • OuterElement 的子元素是定义为序列还是选择?
  • 它们被定义为一个序列

标签: python xml xslt xpath lxml


【解决方案1】:

一种方法是在 XSLT 中设置一个具有完整序列的虚拟元素模板,然后在处理输入时通过一个模板推送虚拟元素,该模板检查输入是否具有相同名称的元素,如果有,则复制该元素一,否则从虚拟模板元素复制元素:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    exclude-result-prefixes="exsl"
    version="1.0">

  <xsl:param name="template">
    <OuterElement>
        <a></a>
        <b></b>
        <c></c>
        <d></d>
        <e></e>
    </OuterElement>
  </xsl:param>
  
  <xsl:variable name="template-elements" select="exsl:node-set($template)/OuterElement/*"/>

  <xsl:template match="OuterElement">
      <xsl:copy>
          <xsl:apply-templates select="$template-elements">
              <xsl:with-param name="input" select="."/>
          </xsl:apply-templates>
      </xsl:copy>
  </xsl:template>
  
  <xsl:template match="OuterElement/*">
      <xsl:param name="input"/>
      <xsl:choose>
          <xsl:when test="$input/*[name() = name(current())]">
              <xsl:copy-of select="$input/*[name() = name(current())]"/>
          </xsl:when>
          <xsl:otherwise>
              <xsl:copy-of select="."/>
          </xsl:otherwise>
      </xsl:choose>
  </xsl:template>
  
  <xsl:output indent="yes"/>
  
</xsl:stylesheet>

很遗憾,对于 XSLT 1,我们需要使用 exsl:node-set 函数将参数结果树片段转换为节点集。

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2021-12-12
    • 1970-01-01
    • 2012-06-11
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多