如何添加到元素,如果需要,首先创建它

时间:2012-03-08 06:01:51

标签: xslt xslt-1.0

我需要向元素添加元素,如果元素尚不存在则首先创建元素。

添加ABC和DEF后,我想要的最终结果是:

<?xml version="1.0" encoding="utf-8"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Q/>
  <B>
    <string>ABC</string>
    <string>DEF</string>
  </B>
<A>

我认为以下内容可以做到这一点:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <!-- Insert a B element if it doesn't exist. -->
  <xsl:template match="A[not(B)]">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
        <B/>
    </xsl:copy>
  </xsl:template>

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

</xsl:stylesheet>

如果我从以下开始,其中&lt; B&gt;已经存在,它工作正常,返回上面的结果:

<?xml version="1.0" encoding="utf-8"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org
  <Q/>
  <B/>
</A>

但是,如果我没有&lt; B&gt;,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org
  <Q/>
</A>

然后它创建&lt; B&gt;如下所示,但不插入ABC和DEF:

<?xml version="1.0" encoding="utf-8"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org
  <Q/>
  <B/>
</A>

那么,我错过了什么?提前谢谢。

3 个答案:

答案 0 :(得分:3)

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

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

    <!-- Insert a B element with string elements if it doesn't exist. -->
    <xsl:template match="A[not(B)]">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
            <B>
                <xsl:call-template name="add-strings"/>
            </B>
        </xsl:copy>
    </xsl:template>

    <!-- Add string elements to existing B if missing -->
    <xsl:template match="B[not(string)]">
        <xsl:copy>
            <xsl:call-template name="add-strings"/>
        </xsl:copy>
    </xsl:template>

    <!-- Add string elements to caller -->
    <xsl:template name="add-strings">
        <string>ABC</string>
        <string>DEF</string>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

当B不存在时,您也必须添加B的子标签,如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>
  <!-- Identity transform -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Insert a B element if it doesn't exist. -->
  <xsl:template match="A[not(B)]">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
        <B>
           <string>ABC</string>
          <string>DEF</string>
       </B>
    </xsl:copy>
  </xsl:template>

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

</xsl:stylesheet>

应用于

<?xml version="1.0" encoding="UTF-8"?>
<root>
<A>
  <Q/>
</A>
<A>
  <Q/>
  <B/>
</A>
</root>

这给出了

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <A>
        <Q/>
        <B>
            <string>ABC</string>
            <string>DEF</string>
        </B>
    </A>
    <A>
        <Q/>
        <B>
            <string>ABC</string>
            <string>DEF</string>
        </B>
    </A>
</root>

答案 2 :(得分:1)

Empo的答案非常接近,但如果&lt; B&gt;已包含&lt; string&gt;元素,新的&lt; string&gt; s未添加。我做了两个小改动,解决了这个问题:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <!-- Insert a B element with string elements if it doesn't exist. -->
  <xsl:template match="A[not(B)]">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
      <B>
        <xsl:call-template name="add-strings"/>
      </B>
    </xsl:copy>
  </xsl:template>

  <!-- Add string elements to existing B element. -->
  <xsl:template match="B">  <!-- Whether there are <string>s or not. -->
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>  <!-- Keep existing <string>s. -->
      <xsl:call-template name="add-strings"/>
    </xsl:copy>
  </xsl:template>

  <!-- Add string elements to caller. -->
  <xsl:template name="add-strings">
    <string>ABC</string>
    <string>DEF</string>
  </xsl:template>

</xsl:stylesheet>