如果另一个属性具有使用 XSLT 的特定值,则重命名 xml 属性值

Renaming xml attribute value if another attribute has a specific value using XSLT

我正在尝试根据特定条件使用 XSLT 将我的输入 xml 转换为输出 xml。

我的输入xml:

<top>
<type>Random value</type>
<attribute name="a"/>
<attribute name="b"/>
...
<attribute name="n"/>
  <attribute name="some value">
    <mapResponses>
      <entryMap name="value1">
        <section>
          <type>STATUS_RESPONSE</type>
          <attribute name="status_code" value="1001" />
          <attribute name="status_detail" value="OK" />
          <attribute name="type" value="Row Line" />
          <attribute name="abc" value="def" />
          ...
          <attribute name="hju" value="tyu" />
        </section>
      </entryMap>
      <entryMap name="value2">
        <section>
          <type>STATUS_RESPONSE</type>
          <attribute name="status_code" value="1001" />
          <attribute name="status_detail" value="OK" />
          <attribute name="type" value="Column value" />
          <attribute name="mno" value="pqr" />
          ...
          <attribute name="olp" value="tre" />
        </section>
      </entryMap>
      <entryMap name="value3">
        <section>
          <type>STATUS_RESPONSE</type>
          <attribute name="status_code" value="1001" />
          <attribute name="status_detail" value="OK" />
          <attribute name="type" value="Other random value" />
          <attribute name="oui" value="fry" />
          ...
          <attribute name="tgy" value="adr" />
        </section>
      </entryMap>
      <entryMap name="value4">
        <section>
         .....
        </section>
      </entryMap>
       <entryMap name="...">
        <section>
         .....
        </section>
      </entryMap>
    </mapResponses>
  </attribute>
</top>

要转换为此输出 xml :

<top>
<type>Random value</type>
<attribute name="a"/>
<attribute name="b"/>
...
<attribute name="n"/>
  <attribute name="some value">
    <mapResponses>
      <entryMap name="value1">
        <section>
          <type>CREATE_ROW</type>
          <attribute name="status_code" value="1001" />
          <attribute name="status_detail" value="OK" />
          <attribute name="type" value="Row Line" />
          <attribute name="abc" value="def" />
          ...
          <attribute name="hju" value="tyu" />
        </section>
      </entryMap>
      <entryMap name="value2">
        <section>
          <type>CREATE_COLUMN</type>
          <attribute name="status_code" value="1001" />
          <attribute name="status_detail" value="OK" />
          <attribute name="type" value="Column value" />
          <attribute name="mno" value="pqr" />
          ...
          <attribute name="olp" value="tre" />
        </section>
      </entryMap>
      <entryMap name="value3">
        <section>
          <type>CREATE_COLUMN</type>
          <attribute name="status_code" value="1001" />
          <attribute name="status_detail" value="OK" />
          <attribute name="type" value="Other random value" />
          <attribute name="oui" value="fry" />
          ...
          <attribute name="tgy" value="adr" />
        </section>
      </entryMap>
      <entryMap name="value4">
        <section>
         .....
        </section>
      </entryMap>
       <entryMap name="...">
        <section>
         .....
        </section>
      </entryMap>
    </mapResponses>
  </attribute>
</top>

因此,当我有 <attribute name="type" value="Row Line" /> 时,<type>STATUS_RESPONSE</type> 需要更改为 <type>CREATE_ROW</type>。当我有 <attribute name="type" value="Column value" /><attribute name="type" value="Other random value" /> 或任何值不是行线的 <attribute name="type" value="..." /> 时,<type>STATUS_RESPONSE</type> 需要更改为 <type>CREATE_COLUMN</type>。 提到 ... 是为了概括 xml 它可以包含更多内容,但级别相同。 <attribute name="type" value="..." /> 始终位于 STATUS_RESPONSE 之后的第 3 个位置,如输入和输出 xml.

中所述

我当前的 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:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
    <xsl:template match="type">
      <xsl:for-each select="attribute[@name='type'][@value='Row Line']">
        <xsl:copy/>
        <xsl:value-of select="CREATE_ROW"/>
      </xsl:for-each>
    </xsl:template>
  
    <xsl:template match="type">
      <xsl:for-each select="attribute[@name='type'][@value!='Row Line']">
        <xsl:copy/>
        <xsl:value-of select="CREATE_COLUMN"/>
      </xsl:for-each>
    </xsl:template>  
</xsl:stylesheet>

我无法从此 XSLT 获得所需的输出。我是 XSLT 的新手,我才刚刚开始研究它。请帮我解决这个问题。谢谢!

您有两个模板都匹配 type(因此样式表中的最后一个将“获胜”),然后您有一个 for 循环正在寻找 attribute 元素,这些元素是 type(有none,因为他们是兄妹)。

将匹配type元素的条件移动到谓词中,寻找following-sibling::轴上的attribute元素,在第二个模板中,不需要断言@value 不等于 'Row Line',因为另一个匹配时已经匹配(并且避免了 != 在大多数人真正意思是 not(@value='Row Line') 的集合上的任何潜在问题)。 =21=]

<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:strip-space elements="*"/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="type[following-sibling::attribute[@name='type' and @value='Row Line']]">
        <xsl:copy>CREATE_ROW</xsl:copy>
    </xsl:template>
    
    <xsl:template match="type[following-sibling::attribute[@name='type']]">
        <xsl:copy>CREATE_COLUMN</xsl:copy>
    </xsl:template>  

</xsl:stylesheet>