使用RegEx重命名XML标记

时间:2014-05-28 16:29:51

标签: xml regex

我从一个XML文件导入了大量员工。每位员工都有一个名为<officeData>的部分和一个名为<personalData>的部分。这两个节点的子节点看起来完全相同,并且具有相同的名称<dataItem>

我想使用将<personalData>中的元素更改为<personalDataItem>,但由于<officeData>节点的子节点,显然无法使用全局搜索/替换。如果我使用回顾/向前看以检查我是否在<personalData>内,它将找到上一个或下一个员工的标签。

无论如何,我可以指定一个正则表达式模式,只重命名特定父XML节点中的多个子节点吗?

2 个答案:

答案 0 :(得分:4)

这不是正则表达式的工作,但使用XSLT样式表会很简单:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

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

  <!-- ... except dataItem inside personalData, which we rename -->
  <xsl:template match="personalData/dataItem">
    <personalDataItem>
      <xsl:apply-templates select="@*|node()" />
    </personalDataItem>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

这种情况直接来自Match (or replace) a pattern except in situations s1, s2, s3 etc

关于使用正则表达式解析xml的所有免责声明,这是一种简单的方法。

这是我们简单的正则表达式:

<officeData>.*?</officeData>|(dataItem>)

交替的左侧匹配完整的officeData标签。我们将忽略这些匹配。右侧匹配并捕获dataItem>到组1,我们知道它们是正确的dataItem>,因为它们与左侧的表达式不匹配。

online demo上,注意如何突出显示正确的dataItem>并将其捕获到第1组,如右下方面板所示。

在您的语言中,在替换功能中,您只需查看是否设置了组1捕获。如果是,则将匹配替换为personalDataItem>。如果没有,你将匹配替换为自己(即没有变化)。

这是一项简单的任务,但是,根据您的语言,您可以在参考文章中找到代码示例来进行第1组检查。

参考

  1. How to match (or replace) a pattern except in situations s1, s2, s3...
  2. How to match a pattern unless...