2015-03-10 4 views
1

Это мой Xml файлаКак добавить ко всем дочерним элементам узла атрибуты другого узла в XSLT?

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

ответ

1

Вместо того, чтобы просто отображать идентификатор записи один раз во внешнем for-each, вы должны переместить этот код в блок внутренний for-each. Попробуйте это - обратите внимание, я также упрощены все xsl:text и xsl: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;').

+0

Ian спасибо за быстрый ответ. Это было решение, которое я искал :) – user1997340

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