选择/匹配xslt的子元素

时间:2016-06-09 00:26:58

标签: xml xslt xpath

很抱歉这个问题很长

我有以下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标签。

有什么建议吗?

1 个答案:

答案 0 :(得分: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>