2012-11-28 56 views
2

得到節點我在XSLT初學者,我用它來轉換XML到XMLXSLT通過指數

這是源XML我收到

源XML:

<Response> 
    <Pax> 
     <Id>1</Id> 
    </Pax> 
    <Pax> 
     <Id>2</Id> 
    </Pax> 
    <Travelers> 
     <Traveler> 
      <Name>ABC</Name> 
     </Traveler> 
     <Traveler> 
      <Name>XYZ</Name> 
     </Traveler> 
    </Travelers> 
</Response> 

我在下面寫了XSLT

XSLT:

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

    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="Response"> 
     <xsl:element name="Root"> 
       <xsl:apply-templates select="Travelers/Traveler"/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="Traveler"> 
      <xsl:element name="Person"> 
      <xsl:element name="PId"> 
        <xsl:value-of select="//Pax/Id[position()]" /> 
      </xsl:element> 
      <xsl:element name="Name"> 
        <xsl:value-of select="Name" /> 
      </xsl:element> 
      </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<Root> 
    <Person> 
    <PId>1</PId> 
    <Name>ABC</Name> 
    </Person> 
    <Person> 
    <PId>1</PId> 
    <Name>XYZ</Name> 
    </Person> 
</Root> 

我想生成下面的XML輸出

預期輸出:

<Root> 
    <Person> 
    <PId>1</PId> 
    <Name>ABC</Name> 
    </Person> 
    <Person> 
    <PId>2</PId> 
    <Name>XYZ</Name> 
    </Person> 
</Root> 

如圖上面的XML唯一的問題是與PId,它應該有價值2

請幫忙。謝謝。

回答

4

這是一個相對簡單的解決方案。

當這個XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output omit-xml-declaration="yes" indent="yes" /> 
    <xsl:strip-space elements="*" /> 

    <xsl:template match="/*"> 
    <Root> 
     <xsl:apply-templates select="Pax" /> 
    </Root> 
    </xsl:template> 

    <xsl:template match="Pax"> 
    <xsl:variable name="vPosition" select="position()" /> 
    <Person> 
     <PId> 
     <xsl:value-of select="Id" /> 
     </PId> 
     <Name> 
     <xsl:value-of select="/*/Travelers/*[$vPosition]/Name" /> 
     </Name> 
    </Person> 
    </xsl:template> 
</xsl:stylesheet> 

......被應用於原始XML:

<Response> 
    <Pax> 
    <Id>1</Id> 
    </Pax> 
    <Pax> 
    <Id>2</Id> 
    </Pax> 
    <Travelers> 
    <Traveler> 
     <Name>ABC</Name> 
    </Traveler> 
    <Traveler> 
     <Name>XYZ</Name> 
    </Traveler> 
    </Travelers> 
</Response> 

......想要的結果產生:

<Root> 
    <Person> 
    <PId>1</PId> 
    <Name>ABC</Name> 
    </Person> 
    <Person> 
    <PId>2</PId> 
    <Name>XYZ</Name> 
    </Person> 
</Root> 
+0

正確。如果你有這些屬性,通常你可以使用'current()',即'// Pax/Id [@id = current()/ @ id]'來繞過這個問題。然而,你不能將'position()'與'current()'結合起來,並且必須求助於使用變量。 –

+0

@NilsWerner - 你是對的。 – ABach

+0

@ABach - 謝謝!已經指定的XPath,是不正確的? –

1
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:template match="Response"> 
    <Root> 
     <xsl:for-each select="Travelers/Traveler"> 
     <Person> 
      <xsl:variable name="index" select="position()" /> 
      <Pid><xsl:value-of select="//Pax[$index]/Id"/></Pid> 
      <Name><xsl:value-of select="Name"/></Name> 
     </Person> 
     </xsl:for-each> 
    </Root> 
    </xsl:template> 
</xsl:stylesheet> 
0
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml"/> 
    <xsl:template match="/Response"> 
     <Root> 
      <xsl:for-each select="Pax"> 
       <xsl:variable name="pos" select="position()"/> 
       <Person> 
        <PId> 
         <xsl:value-of select="Id"/> 
        </PId> 
        <xsl:apply-templates select="//Travelers"> 
         <xsl:with-param name="pos" select="$pos"/> 
        </xsl:apply-templates> 
       </Person> 
      </xsl:for-each> 
     </Root> 
    </xsl:template> 
    <xsl:template match="Travelers"> 
     <xsl:param name="pos"/> 
     <xsl:for-each select="//Name"> 
      <xsl:if test="position()=$pos"> 
       <xsl:copy-of select="."/> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet>