从特定的父节点复制子节点并更改子节点的值

时间:2019-09-11 15:18:52

标签: xml xslt

我想复制每个节点(第一个节点)并根据源XML中的值更改子节点的值。

我能够复制节点并根据源值更改标签的值。但是我无法复制其余节点,例如App,标头,数据,发件人...

源XML:

<root>
    <App>
        <header>
            <sender>
                <name>PC1</name>
            </sender>
        </header>
        <data>
            <A></A>
            <B></B>
            <C></C>
        </data>
    </App>
</root>

XSLT:

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

    <xsl:template match="/root/App/header/sender">
        <xsl:choose>
            <xsl:when test="name">
                <xsl:apply-templates select="name" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:element name="name">
                    <xsl:value-of select="'Desktop'" />
                </xsl:element>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="/root/App/header/sender/name">
    <xsl:element name="name">
        <xsl:choose>
            <xsl:when test="not(string(.))">
                <xsl:value-of select="'Desktop'" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat('Desktop-',.)" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:element>
</xsl:template>

当前输出:

<root>
   <name>Desktop-PC1</name>
</root>

预期输出:

<App>
    <header>
        <sender>
            <!-- if tag <name> has some value -> add prefix "Desktop-" -->
            <name>Desktop-PC1</name>

            <!-- if tag <name> has empty value or whole tag missing  -> add default value "Desktop" 
            <name>Desktop</name>
            --> 
        </sender>
    </header>
    <data>
        <A></A>
        <B></B>
        <C></C>
    </data>
</App>

1 个答案:

答案 0 :(得分:2)

对于此类任务,我总是从身份转换模板开始,然后在该特定元素(只要可用)上进行匹配,或者在子项不可用时在父项上进行匹配:

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

  <xsl:param name="default" select="'Desktop'"/>

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

  <xsl:template match="App/header/sender/name[normalize-space()]">
      <xsl:copy>
          <xsl:value-of select="$default"/>-<xsl:value-of select="."/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="App/header/sender/name[not(normalize-space())]">
      <xsl:copy>
          <xsl:value-of select="$default"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="App/header/sender[not(name)]">
      <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <name>
            <xsl:value-of select="$default"/>
          </name>
          <xsl:apply-templates/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bwdwrB/0https://xsltfiddle.liberty-development.net/bwdwrB/1https://xsltfiddle.liberty-development.net/bwdwrB/2

然后通过为该App添加一个仅使用root root元素的apply-templates子元素的转换任务。 >

  <xsl:template match="root">
      <xsl:apply-templates/>
  </xsl:template>

https://xsltfiddle.liberty-development.net/bwdwrB/3

相关问题