2016-06-09 176 views
0

很抱歉的長期問題選擇/於子元素匹配的XSLT

我有下面的XML

<?xml version="1.0"?> 
<body> 
    <payload> 
    <TextBook> 
     <Title>Maths Book</Title> 
     <Modified>2001-10-1</Modified> 
     <AuditTrails> 
     <AuditTrail> 
      <Modified>2001-1-4</Modified> 
      <User>ABC</User> 
     </AuditTrail> 
     </AuditTrails> 
     <Authors> 
     <Author> 
      <Modified>1999-1-2</Modified> 
      <Name>Steven</Name> 
     </Author> 
     </Authors> 
    </TextBook> 
</payload> 
<payload> 
<FictionBook> 
    <Title>Star Trek</Title> 
    <Modified>2001-10-2</Modified> 
    <AuditTrails> 
     <AuditTrail> 
      <Modified>2001-1-5</Modified> 
      <User>ABC</User> 
     </AuditTrail> 
    </AuditTrails> 
</FictionBook> 
</payload> 
</body> 

我想將其轉換成以下的輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<Books> 
<Book> 
    <title1>Maths Book</title1> 
    <CreatedDate>2001-10-1</CreatedDate> 
    <Author>Steven</Author> 
</Book> 
<Book> 
    <title1>Star Trek</title1> 
    <CreatedDate>2001-10-2</CreatedDate> 
</Book> 
</Books> 

我有90%的出路:

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

<!-- book --> 
<xsl:template match="/body"> 
<Books> 
    <xsl:for-each select="payload/child::*"> 
    <Book> 
     <title> 
     <xsl:value-of select="Title"/> 
     </title> 
     <xsl:apply-templates/> 
    </Book> 
    </xsl:for-each> 
</Books> 
</xsl:template> 

<!-- override default templates --> 
<xsl:template match="text()"/> 

<!-- modified --> 
<xsl:template match="Modified"> 
<CreatedDate> 
    <xsl:value-of select="text()"/> 
</CreatedDate> 
</xsl:template> 

<!-- author --> 
<xsl:template match="Authors/Author[1]/Name"> 
<Author> 
    <xsl:value-of select="text()"/> 
</Author> 
</xsl:template> 

</xsl:stylesheet> 

的問題是,我只希望每本書一個「CreatedDate」節點,而不是孩子/孫子那麼這個XSLT目前輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<Books> 
<Book> 
    <title1>Maths Book</title1> 
    <CreatedDate>2001-10-1</CreatedDate> 
    <CreatedDate>2001-1-4</CreatedDate> 
    <CreatedDate>1999-1-2</CreatedDate> 
    <Author>Steven</Author> 
</Book> 
<Book> 
    <title1>Star Trek</title1> 
    <CreatedDate>2001-10-2</CreatedDate> 
    <CreatedDate>2001-1-5</CreatedDate> 
</Book> 
</Books> 

如果我添加:

<xsl:template match="*"/> 

然後輸出CreatedDate如我所料 - 但現在缺少Author標籤。

有什麼建議嗎?

回答

0

這個怎麼樣模板

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

    <xsl:template match="/"> 
    <Books> 
     <xsl:apply-templates select="//payload/*"/> 
    </Books> 
    </xsl:template> 

    <xsl:template match="payload/*"> 
    <Book> 
     <title> 
     <xsl:value-of select="Title"/> 
     </title> 
     <xsl:apply-templates/> 
    </Book> 
    </xsl:template> 

    <xsl:template match="Authors/Author[1]"> 
    <xsl:copy> 
     <xsl:value-of select="Name"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="payload/*/Modified"> 
    <CreatedDate> 
     <xsl:value-of select="text()"/> 
    </CreatedDate> 
    </xsl:template> 

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

</xsl:stylesheet> 
+0

我一直在尋找一個解決方案,由此我可以繼續修改後的比賽。以上只是一個簡單的例子,在我的應用程序中,在修改後的字段上這種模式匹配做了很多,我希望它可以重複使用 – Stuart

+0

@Stuart,我已經更新了我的回答 –

+0

感謝您的替代方法。在xsl:apply-templates中可以選擇直接的孩子嗎? – Stuart