【问题标题】:Remove all xml parents, keep ones with specific children (regular expression)删除所有 xml 父项,保留具有特定子项的项(正则表达式)
【发布时间】:2023-01-03 13:25:08
【问题描述】:

我很想删除每个不包含特定值的父母,例如

<drawableDictionary>l_njdocklod12</drawableDictionary>

下面的 XML 示例:

<?xml version="1.0" encoding="UTF-8"?>
<CMapTypes name="lodetnjdock_wh1">
 <extensions />
 <archetypes>
  <Item type="CBaseArchetypeDef">
   <lodDist value="550" />
   <flags value="0" />
   <specialAttribute value="0" />
   <bbMin x="-12.3383" y="-6.42445" z="-13.3852" />
   <bbMax x="12.3382" y="6.42445" z="13.3852" />
   <bsCentre x="-5.05447E-05" y="2.38419E-06" z="0" />
   <bsRadius value="19.3046" />
   <hdTextureDist value="0" />
   <name>hash_349C91C8</name>
   <textureDictionary>njdocklod04</textureDictionary>
   <clipDictionary />
   <drawableDictionary>lodnjdocksuper11_grp</drawableDictionary>
   <physicsDictionary>nj_docks</physicsDictionary>
   <assetType>ASSET_TYPE_DRAWABLEDICTIONARY</assetType>
   <assetName>hash_349C91C8</assetName>
   <extensions />
  </Item>
  <Item type="CBaseArchetypeDef">
   <lodDist value="550" />
   <flags value="0" />
   <specialAttribute value="0" />
   <bbMin x="-5.6393" y="-5.45088" z="-4.9861" />
   <bbMax x="5.6393" y="5.45088" z="4.9861" />
   <bsCentre x="0" y="-4.76837E-07" z="4.76837E-07" />
   <bsRadius value="9.29382" />
   <hdTextureDist value="0" />
   <name>hash_46EE366B</name>
   <textureDictionary>njdocklod12</textureDictionary>
   <clipDictionary />
   <drawableDictionary>l_njdocklod12</drawableDictionary>
   <physicsDictionary>nj_docks</physicsDictionary>
   <assetType>ASSET_TYPE_DRAWABLEDICTIONARY</assetType>
   <assetName>hash_46EE366B</assetName>
   <extensions />
  </Item>
  <Item type="CBaseArchetypeDef">
   <lodDist value="550" />
   <flags value="0" />
   <specialAttribute value="0" />
   <bbMin x="-11.8993" y="-34.8797" z="-4.27972" />
   <bbMax x="11.8992" y="34.8796" z="4.29434" />
   <bsCentre x="-2.76566E-05" y="-1.52588E-05" z="0.0073123" />
   <bsRadius value="37.102" />
   <hdTextureDist value="0" />
   <name>hash_52EAB9C8</name>
   <textureDictionary>njdocklod10</textureDictionary>
   <clipDictionary />
   <drawableDictionary>lodnjdocksuper05_grp</drawableDictionary>
   <physicsDictionary>nj_docks</physicsDictionary>
   <assetType>ASSET_TYPE_DRAWABLEDICTIONARY</assetType>
   <assetName>hash_52EAB9C8</assetName>
   <extensions />
  </Item>
 </archetypes>
 <name>nj_docks_lod</name>
 <dependencies />
 <compositeEntityTypes itemType="CCompositeEntityType" />
</CMapTypes>

期望的结果

<?xml version="1.0" encoding="UTF-8"?>
<CMapTypes name="lodetnjdock_wh1">
 <extensions />
 <archetypes>
  <Item type="CBaseArchetypeDef">
   <lodDist value="550" />
   <flags value="0" />
   <specialAttribute value="0" />
   <bbMin x="-5.6393" y="-5.45088" z="-4.9861" />
   <bbMax x="5.6393" y="5.45088" z="4.9861" />
   <bsCentre x="0" y="-4.76837E-07" z="4.76837E-07" />
   <bsRadius value="9.29382" />
   <hdTextureDist value="0" />
   <name>hash_46EE366B</name>
   <textureDictionary>njdocklod12</textureDictionary>
   <clipDictionary />
   <drawableDictionary>l_njdocklod12</drawableDictionary>
   <physicsDictionary>nj_docks</physicsDictionary>
   <assetType>ASSET_TYPE_DRAWABLEDICTIONARY</assetType>
   <assetName>hash_46EE366B</assetName>
   <extensions />
  </Item>
 </archetypes>
 <name>nj_docks_lod</name>
 <dependencies />
 <compositeEntityTypes itemType="CCompositeEntityType" />
</CMapTypes>

我想实现这个使用正则表达式,使用 Notepad++,因为我离这里的舒适区很远,到目前为止这对我有用。

【问题讨论】:

  • Notepad++ 不是修改 XML 的正确工具。使用应该存在于您最喜欢的脚本语言中的解析器。
  • 但是它确实在很多情况下会修改xml,这正是我现在所需要的。如果我有最喜欢的脚本语言,我就不会在这里寻求帮助。

标签: regex xml notepad++


【解决方案1】:

完成这项工作的工具是 XSLT。这是一个非常简单的转换:一个复制所有内容不变的身份模板加上一个删除不需要的项目的规则:

<xsl:template match="Item[not(drawableDictionary='l_njdocklod12')]"/>

在 XSLT 3.0 中,您可以通过编写获得标识模板

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

在旧版本中,写

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

【讨论】:

    【解决方案2】:

    可以搜索所有不包含该值的&lt;Item&gt;元素 l_njdocklod12 使用这个正则表达式:
    &lt;Item((?!l_njdocklod12).)*?&lt;/Item&gt;$

    请注意,(?! 是前瞻性的,以验证您的字符串不存在。
    我使用*? 进行非贪婪匹配。

    确保选中 . matches newline

    要删除找到的匹配项,请将它们替换为空字符串。

    【讨论】:

    • 这个答案可能适用于这个例子,但总的来说它是完全错误的,任何使用正则表达式解决问题的尝试都是错误的。例如,如果 XML 包含 cmets,或者如果它在意想不到的地方包含空格,或者如果它包含文本值为“l_njdocklod12”的元素,它可能会失败。仅当您乐于编写仅在 99% 的时间内有效的代码时,才使用这种代码。使用正则表达式来操作 XML 是非常糟糕的做法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 2012-03-16
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 2012-06-22
    相关资源
    最近更新 更多