如何在XSLT中向节点的所有子节点添加另一个节点的属性?

时间:2015-03-10 11:27:12

标签: xml csv xslt

这是我的Xml文件

 <?xml version="1.0" encoding="UTF-8"?>
    <records>
    <REC>
        <ID>000173379701048</ID>
        <static_data>
          <summary>
            <names count="2">
              <name>
                <display_name>TT</display_name>
                <full_name>TT</full_name>
              </name>
              <name>
                <display_name>NM</display_name>
                <full_name>NM</full_name>
              </name>
            </names>
          </summary>
     </static_data>
    <REC>
    </records>

到目前为止,使用此XSLT代码我得到以下结果

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:for-each select="/records/REC">
             <xsl:text>&#34;</xsl:text>
             <xsl:value-of select="ID" />
             <xsl:text>&#34;</xsl:text>
             <xsl:value-of select ="','"/>

     <xsl:for-each select="static_data/summary/names/name">
                <xsl:text>&#34;</xsl:text>
                <xsl:value-of select="display_name" />
                <xsl:text>&#34;</xsl:text>
                <xsl:value-of select ="','"/>

                <xsl:text>&#34;</xsl:text>
                <xsl:value-of select="full_name" />
                <xsl:text>&#34;</xsl:text>
                <xsl:value-of select ="','"/>
       </xsl:for-each>

       </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

我在csv文件中的结果是

 "000173379701048", "TT", "TT",
 "NM", "NM",

我期望得到的是

"000173379701048", "TT", "TT",
"000173379701048", "NM", "NM",

欢迎任何建议,因为我是xslt的新手:)

3 个答案:

答案 0 :(得分:1)

您需要将该代码移至内部for-each,而不是仅在外部for-each中显示一次记录ID。试试这个 - 请注意我还将所有xsl:textxsl:value-of部分简化为一个concat

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:for-each select="/records/REC">
      <xsl:variable name="id" select="ID" /><!-- question said UID but input has ID -->
      <xsl:for-each select="static_data/summary/names/name">
         <xsl:value-of select="concat(
             '&quot;', $id, '&quot;,',
             '&quot;', display_name, '&quot;,',
             '&quot;', full_name, '&quot;,')"/>
         </xsl:for-each>
     </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

(虽然这会在一条长行上打印所有内容,大概是你真的想把东西放在不同的行上,在这种情况下用'&quot;,'替换最后的'&quot;&#10;'。)

答案 1 :(得分:0)

试试这个:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/records/REC">
        <xsl:apply-templates select="static_data/summary/names/name"/>
    </xsl:template>
    <xsl:template match="name">
        <xsl:text>"</xsl:text>
        <xsl:value-of select="../../../../ID" />
        <xsl:text>"</xsl:text>
        <xsl:text>,</xsl:text>
        <xsl:text>"</xsl:text>
        <xsl:value-of select="display_name" />
        <xsl:text>",</xsl:text>
        <xsl:text>"</xsl:text>
        <xsl:value-of select="full_name" />
        <xsl:text>",</xsl:text>
        <xsl:if test="position() != last()">
            <xsl:text>&#xa;</xsl:text>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

答案 2 :(得分:0)

诀窍是编写一个匹配name节点的模板,并使用父轴获取ID。其他改进:

  • 创建文本文件时,请确保将输出方法设置为文本。
  • 您可以通过添加额外的模板来引用CSV值来避免重复。请注意使用mode属性。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/">
    <xsl:apply-templates select="records/REC/static_data/summary/names/name"/>
</xsl:template>

<xsl:template match="name">
    <xsl:apply-templates select="../../../../ID" mode="quote"/>
    <xsl:text>,</xsl:text>
    <xsl:apply-templates select="display_name" mode="quote"/>
    <xsl:text>,</xsl:text>
    <xsl:apply-templates select="full_name" mode="quote"/>
    <xsl:text>&#10;</xsl:text>
</xsl:template>

<xsl:template match="*" mode="quote">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="."/>
    <xsl:text>"</xsl:text>
</xsl:template>

</xsl:stylesheet>