2017-07-20 3 views
0

Ich bin neu in XSLT und ich versuche, ein Eingabe-XML in ein anderes zu verwandeln, indem Sie die folgenden Elementwerte in Attribute verketten. Gibt es einen Weg, wie ich das mit XSLT machen kann?Verketten Sie mehrere XML-Elementwerte in einem einzelnen Elementattribut

Eingang xml:

<requests> 
    <request> 
    <name>BLA1</name> 
    <age>42</age> 
    </request> 
    <request> 
    <name>BLA2</name> 
    <age>24</age> 
    </request> 
</requests> 

Ergebnis xml:

<bodyParams> 
    <param name='name' value='BLA1,BLA2' /> 
    <param name='age' value='42,24' /> 
</bodyParams> 

Vielen Dank für die Hilfe im Voraus!

+0

Haben Sie XSLT 1.0 oder 2.0 verwenden? – zx485

Antwort

1

Das Folgende ist eine XSLT-1.0-Lösung.
Die param Namen stammen aus dem request Element der Kinder name(). Die xsl:if prüft, ob es das letzte Element ist, wenn nicht, gibt es das Trennzeichen (Trennzeichen in XSLT-1.0) aus.

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

<xsl:template match="/requests"> 
    <bodyParams> 
     <xsl:for-each select="request[1]/*">    <!-- iterate over children's names of the first request element --> 
     <xsl:variable name="curPos" select="name()" /> <!-- remember its name --> 
     <xsl:element name="param">      <!-- construct <param name="..." value="..." /> element --> 
      <xsl:attribute name="name"><xsl:value-of select="name()" /></xsl:attribute> 
      <xsl:attribute name="value"><xsl:for-each select="//request/*[name()=$curPos]"> 
       <xsl:value-of select="normalize-space(.)" /><xsl:if test="position() != last()"><xsl:text>,</xsl:text></xsl:if> 
      </xsl:for-each></xsl:attribute> 
     </xsl:element> 
     </xsl:for-each> 
     <xsl:apply-templates select="@*|node()" /> 
    </bodyParams> 
</xsl:template> 

<xsl:template match="text()" /> 
</xsl:stylesheet> 
+0

Sorry, ich habe vergessen zu erwähnen, dass ich die 1.0-Lösung brauchte. Danke für deine Antwort, das hat mein Problem gelöst. – Fragosus

2

Mit XSLT 2.0 oder 3.0 Sie

<xsl:template match="requests"> 
    <bodyParams> 
     <xsl:for-each-group select="request/*" group-by="node-name(.)"> 
      <param name="{current-grouping-key()}" value="{string-join(current-group(), ',')}"/> 
     </xsl:for-each-group> 
    </bodyParams> 
</xsl:template> 
1

Unter der Annahme, alle request Elemente haben den gleichen untergeordneten Knoten, in der gleichen Reihenfolge verwenden könnten, das ist, wie ich diese 1,0 in XSLT lösen würde:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:template match="/requests"> 
    <bodyParams> 
     <xsl:for-each select="request[1]/*"> 
      <xsl:variable name="i" select="position()" /> 
      <param name="{name()}"> 
       <xsl:attribute name="value"> 
        <xsl:for-each select="../../request/*[$i]"> 
         <xsl:value-of select="." /> 
         <xsl:if test="position()!=last()"> 
          <xsl:text>,</xsl:text> 
         </xsl:if> 
        </xsl:for-each> 
       </xsl:attribute> 
      </param> 
     </xsl:for-each> 
    </bodyParams> 
</xsl:template> 

</xsl:stylesheet> 
2

Hier einige andere Methode ...

<xsl:template match="requests"> 
     <xsl:variable name="name"> 
      <xsl:value-of select="for $x in . return if ($x//name) then $x//name else ''" separator=","/> 
     </xsl:variable> 
     <xsl:variable name="age"> 
      <xsl:value-of select="for $x in . return if ($x//age) then $x//age else ''" separator=","/> 
     </xsl:variable> 
     <bodyparams> 
      <param name="name" value="{$name}"/> 
      <param name="age" value="{$age}"/> 
     </bodyparams> 
    </xsl:template> 

oder

<xsl:template match="requests"> 
     <xsl:variable name="name"> 
      <xsl:value-of select="for $x in . return if ($x/request/*[1]) then $x/request/*[1] else ''" separator=","/> 
     </xsl:variable> 
     <xsl:variable name="age"> 
      <xsl:value-of select="for $x in . return if ($x/request/*[2]) then $x/request/*[2] else ''" separator=","/> 
     </xsl:variable> 
     <bodyparams> 
      <param name="name" value="{$name}"/> 
      <param name="age" value="{$age}"/> 
     </bodyparams> 
    </xsl:template> 
+0

IMHO, 'name' und' age' sind nur ein Beispiel und sollen nicht hartcodiert werden. –

Verwandte Themen