复制行并替换字符串

Duplicate line and replace string

我有一个包含 10,000 多个项目的 XML 文件。每个项目都包含这样一行。

<g:id><![CDATA[FBM00101816_BLACK-L]]></g:id>

对于每个项目,我需要在下面添加另一行,如下所示:

<sku><![CDATA[FBM00101816]]></sku>

所以我需要复制每个 g:id 行,将 g:id 替换为 sku 和 trim 删除下划线(包括它)之后的所有字符的值。最终结果是这样的:

<g:id><![CDATA[FBM00101816_BLACK-L]]></g:id>
<sku><![CDATA[FBM00101816]]></sku>

有什么想法可以实现吗?

提前致谢。

好吧,所以评论之后,我就忍不住了。这似乎满足了您的要求。

find: <g:id><!\[CDATA\[([^\_]+)?(.+)?\]></g:id>
replace: [=10=]\n<sku><![CDATA[]></sku>

我没有 BBEdit,但它在 Textmate 中是这样的:

在 XSLT 中,它是

<xsl:template match="g:id">
  <xsl:copy-of select="."/>
  <sku><xsl:value-of select="substring-before(., '_')"/></sku>
</xsl:template>

或者使用 Saxon 的 Gizmo (https://www.saxonica.com/documentation11/index.html#!gizmo)

follow //g:id with <sku>{substring-before(., '_')}</sku>

不要尝试在文本编辑器(或任何其他不涉及真正 XML 解析器的工具)中执行此类操作,除非它是一次性的。您的代码将对源代码 XML 编写方式的细微变化过于敏感,并且几乎不可避免地会出现错误 - 这对于一次性来说可能无关紧要,但如果它要在一段时间内重复使用则很重要一段时间。

另请注意,输入(和输出)中的 CDATA 标签是一种浪费 space。除非元素内容包含 <& 等特殊字符,否则 CDATA 标记没有任何意义,在您的示例中并非如此。