代码之家  ›  专栏  ›  技术社区  ›  Ray

在一定条件下复制XML文档并添加属性加上生成值的XSLT

  •  1
  • Ray  · 技术社区  · 14 年前

    我有一个XML文档,在某些情况下需要添加属性。

    XML文档非常简单:

    <A x="foo" y="bar" z="">
    <B/>
    <C/></A>
    

    基本上,如果属性“z”存在。然后需要向节点“a”添加一个新属性。属性的值需要是一个文本字符串,在某些位置用“x”和“y”替换。结果应该是:

    <A x="foo" y="bar" z="" new="values present are x=foo and y=bar">
    <B/>
    <C/></A>
    

    我已经创建了一个将文档复制到属性级别的XSLT。但我在尝试创建测试属性z并基于x和y创建字符串的逻辑时遇到了障碍。

    有人能帮忙吗?

    谢谢

    从评论:

    有东西停下来了 我在上面写了一个词根 节点 <R> 包含了一切。R号 节点具有如下属性: xmlns="http://www.fixprotocol.org/FIXML-4-4" . 出于某种原因添加此属性 使匹配“A”的模板

    3 回复  |  直到 10 年前
        1
  •  3
  •   Dimitre Novatchev    14 年前

    更新 :操作已解释(仅在注释中!):

    这些解决方案有效。文本XML 包含全部内容的节点。这个 <R> 节点具有如下属性: xmlns="http://www.fixprotocol.org/FIXML-4-4" . 出于某种原因添加此属性 使匹配“A”的模板

    这可能是最短的

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:x="http://www.fixprotocol.org/FIXML-4-4"
     xmlns="http://www.fixprotocol.org/FIXML-4-4" exclude-result-prefixes="x">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
    
     <xsl:template match="node()|@*">
         <xsl:copy>
           <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
     </xsl:template>
    
     <xsl:template match="x:A[@z]">
      <A new="values present are x={@x} and y={@y}">
       <xsl:apply-templates select="node()|@*"/>
      </A>
     </xsl:template>
    </xsl:stylesheet>
    

    当此转换应用于所提供的XML文档时

    <R xmlns="http://www.fixprotocol.org/FIXML-4-4">
        <A x="foo" y="bar" z="">
            <B/>
            <C/>
        </A>
    </R>
    

    得到想要的正确结果 :

    <R xmlns="http://www.fixprotocol.org/FIXML-4-4">
        <A new="values present are x=foo and y=bar" x="foo" y="bar" z="">
            <B></B>
            <C></C>
        </A>
    </R>
    
        2
  •  1
  •   stapeluberlauf    14 年前

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="A">
        <A>
          <xsl:if test="@z">
            <xsl:attribute name="new">
             <xsl:value-of select="concat('values present are x=',@x,' and y=',@y)"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:apply-templates select="@* | node()"/>
        </A>
    
      </xsl:template>
    </xsl:stylesheet>
    
        3
  •  1
  •   user357812 user357812    14 年前

    编辑 :现在具有正确的命名空间。

    此样式表:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:fixml="http://www.fixprotocol.org/FIXML-4-4">
        <xsl:template match="@*|node()" name="identity">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="fixml:A/@z">
            <xsl:call-template name="identity"/>
            <xsl:attribute name="new">
                <xsl:value-of
                   select="concat('values present are x=',../@x,' and y=',../@y)"/>
            </xsl:attribute>
        </xsl:template>
    </xsl:stylesheet>
    

    <R xmlns="http://www.fixprotocol.org/FIXML-4-4">
        <A x="foo" y="bar" z="">
            <B/>
            <C/>
        </A>
    </R>
    

    输出:

    <R xmlns="http://www.fixprotocol.org/FIXML-4-4">
        <A x="foo" y="bar" z="" new="values present are x=foo and y=bar">
            <B></B>
            <C></C>
        </A>
    </R>