【问题标题】:How to add to all the childs of a node the attributes of another node in XSLT?如何在 XSLT 中将另一个节点的属性添加到节点的所有子节点?
【发布时间】:2015-03-10 11:27:11
【问题描述】:

这是我的 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 的新手 :)

【问题讨论】:

    标签: xml csv xslt


    【解决方案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>
    

    (虽然这会将所有内容都打印在一条长行上,但可能您实际上希望将内容放在单独的行中,在这种情况下,将最后一个 '&amp;quot;,' 替换为 '&amp;quot;&amp;#10;')。

    【讨论】:

    • 伊恩感谢您的快速回答。这是我一直在寻找的解决方案:)
    【解决方案2】:

    试试这个:

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

    【讨论】:

      【解决方案3】:

      诀窍是编写一个与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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多