2012-03-08 57 views
2

我需要将元素添加到元素,如果它尚不存在首先创建它。如何添加到元素,如果需要首先创建它

我期望的最终结果,将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> 

如果我开始与以下,其中<B>已经存在,它工作正常,返回上面的结果:

<?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> 

不过,如果我没有<乙>,如下:

<?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> 

然后创建<乙>如下,但不插入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> 

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

回答

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> 
+0

好吧,那看起来有些蹩脚(XSLT,不是你)。没有办法说要做一条规则,然后再做另一条规则吗? – uncaged 2012-03-08 06:59:26

+0

这需要两次通过;一个XSLT将只运行一次输入节点,只输出和不读取输出节点。 – Maestro13 2012-03-08 07:26:55

2
<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

非常酷!谢谢! – uncaged 2012-03-08 16:25:49

0

Empo的回答非常接近,但如果<B>已包含<字符串>元素,新<字符串> 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> 
+0

除了(在您的问题中未明确暴露),您的问题的解决方案由命名模板提供。 – 2012-03-10 10:23:44

相关问题