2016-06-09 5 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

Смежные вопросы