使用 XSLT 删除不需要的 xml 内容

Removing unwanted xml content using XSLT

我正在使用 XSLT 1.0,并且正在尝试进行此 xml-to-xml 转换:

我的input.xml:

<RootElement>
  <CustomAttr name="GVillage"/>
  .
  .
  <CustomAttr name="RVC">
    <ValStart>
      <RetailAttr name="RVC">
        .
        .
      </RetailAttr>
    </ValStart>
  </CustomAttr>
  <CustomAttr name="GTX">
    <ValStart>
      <RetailAttr name="GTX">
        .
        .
      </RetailAttr>
    </ValStart>
  </CustomAttr>
  .
  .
  .
  <CustomAttr name=".......">
    <ValStart>
      <RetailAttr name=".......">
        .
        .
      </RetailAttr>
    </ValStart>
  </CustomAttr>
  <CustomAttr name="mode" value="DummyValue"/>
  <CustomAttr name="affinity" value="SomeValue"/>
  <CustomAttr name="names" value="SampleValue">
    <list>
      <value>nodevalue</value>
    </list>
  </CustomAttr>
</RootElement>

我的预期 output.xml :

<RootElement>
  <CustomAttr name="GVillage"/>
  .
  .
  <CustomAttr name="ShortCodes">
    <ValStart>
      <RetailAttr name="RVC">
        .
        .
      </RetailAttr>
    </ValStart>
    <ValStart>
      <RetailAttr name="GTX">
        .
        .
      </RetailAttr>
    </ValStart>
  .
  .
  .
    <ValStart>
      <RetailAttr name=".......">
        .
        .
      </RetailAttr>
    </ValStart>
  </CustomAttr>
  <CustomAttr name="mode" value="DummyValue"/>
  <CustomAttr name="affinity" value="SomeValue"/>
  <CustomAttr name="names" value="SampleValue">
    <list>
      <value>nodevalue</value>
    </list>
  </CustomAttr>
</RootElement>

输入 xml 包含元素 <CustomAttr name="RVC"><CustomAttr name="GTX"> 以及随后的任意数量的 <CustomAttr name=".......">,我尝试使用“... ..”。我需要将所有这些元素组合成一个元素 <CustomAttr name="ShortCodes">,它在开头打开一次并在结尾关闭一次(如 output.xml 所示),而不是每次都打开和关闭每个 <RetailAttr name="RVC"> , <RetailAttr name="GTX"> 等。

我目前拥有的 XSLT 是:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  
  <xsl:template match="CustomAttr[@name='RVC']">
    <xsl:copy>
      <xsl:attribute name="name">ShortCodes</xsl:attribute>
      <xsl:copy-of select="//CustomAttr/ValStart"/>
    </xsl:copy>
  </xsl:template>

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

我从这个 XSLT 得到的输出是 xsltoutput.xml:

<?xml version="1.0"?>
<RootElement>
<CustomAttr name="GVillage"></CustomAttr>
  .
  .
<CustomAttr name="ShortCodes">
<ValStart>
<RetailAttr name="RVC">
        .
        .
</RetailAttr>
</ValStart>
<ValStart>
<RetailAttr name="GTX">
        .
        .
</RetailAttr>
</ValStart>
<ValStart>
<RetailAttr name=".......">
        .
        .
</RetailAttr>
</ValStart>
</CustomAttr>
<CustomAttr name="GTX">
<ValStart>
<RetailAttr name="GTX">
        .
        .
</RetailAttr>
</ValStart>
</CustomAttr>
  .
  .
  .
<CustomAttr name=".......">
<ValStart>
<RetailAttr name=".......">
        .
        .
</RetailAttr>
</ValStart>
</CustomAttr>
  <CustomAttr name="mode" value="DummyValue"/>
  <CustomAttr name="affinity" value="SomeValue"/>
  <CustomAttr name="names" value="SampleValue">
    <list>
      <value>nodevalue</value>
    </list>
  </CustomAttr>
</RootElement>

我得到了我需要的转换,但我也在 xsltoutput.xml 中的 </CustomAttr><CustomAttr name="ShortCodes"> 的结束元素)之后复制了不需要的内容,我我无法理解如何删除。

我要删除的 xsltoutput.xml 中不需要的内容:

<CustomAttr name="GTX">
<ValStart>
<RetailAttr name="GTX">
        .
        .
</RetailAttr>
</ValStart>
</CustomAttr>
  .
  .
  .
<CustomAttr name=".......">
<ValStart>
<RetailAttr name=".......">
        .
        .
</RetailAttr>
</ValStart>
</CustomAttr>

因为根据我的输入 xml 要求可以有任意数量的 CustomAttr 元素,所以我正在尝试通用 XSLT。任何形式的帮助将不胜感激。谢谢!

我不确定身份转换是否是一个好的起点,但如果你使用它,看起来你需要 <xsl:template match="CustomAttr[preceding-sibling::CustomAttr[@name='RVC']]"/> 来阻止复制这些元素。

根据您的评论和编辑,<xsl:template match="CustomAttr[ValStart and preceding-sibling::CustomAttr[@name='RVC']]"/> 可能会。