XSLT Transformation将具有相同名称的节点与父节点连接起来

时间:2018-04-17 20:18:20

标签: xslt xpath

我想将以下XML数据转换为下面显示的所需输出 - 直到现在都没有成功。所以我希望有关xsl的专家提供意见。提前谢谢。

输入XML数据

<?xml version="1.0" encoding="utf-8"?>
<pages>
   <page number="1">
     <pageArticles>
         <articleID id="100"/>
         <articleID id="200"/>
         <articleID id="300"/>
     </pageArticles>
   </page>
   <page number="5">
      <pageArticles/>
   </page>
   <page number="9">
      <pageArticles>
         <articleID id="400"/>
         <articleID id="500"/>                 
      </pageArticles>
   </page>
</pages>

所需的输出

<?xml version="1.0" encoding="utf-8"?>
<pages>
  <page>
     <number>1</number>
     <articleID>100</articleID>
  </page>
  <page>
     <number>1</number>
     <articleID>200</articleID>
  </page>
  <page>
     <number>1</number>
     <articleID>300</articleID>
  </page>
  <page>
     <number>5</number>
     <articleID></articleID>
  </page>
  <page>
     <number>9</number>
     <articleID>400</articleID>
  </page>
  <page>
     <number>9</number>
     <articleID>500</articleID>
  </page>
</pages>

非常感谢您的任何帮助! URS

2 个答案:

答案 0 :(得分:1)

这个XSLT-1.0样式表完成了这项工作:

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

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

  <xsl:template match="/pages">
    <xsl:copy>
        <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="//articleID | pageArticles[not(*)]">
    <page>
        <number><xsl:value-of select="ancestor::page/@number[1]" /></number>
        <articleID><xsl:value-of select="@id" /></articleID>
    </page>
  </xsl:template>

</xsl:stylesheet>

输出为:

<pages>
   <page>
      <number>1</number>
      <articleID>100</articleID>
   </page>
   <page>
      <number>1</number>
      <articleID>200</articleID>
   </page>
   <page>
      <number>1</number>
      <articleID>300</articleID>
   </page>
   <page>
      <number>5</number>
      <articleID/>
   </page>
   <page>
      <number>9</number>
      <articleID>400</articleID>
   </page>
   <page>
      <number>9</number>
      <articleID>500</articleID>
   </page>
</pages>

答案 1 :(得分:0)

为那些articleID元素编写模板以从祖父母中收集数字,并为空pageArticles添加模板:

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

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="pages">
      <xsl:copy>
          <xsl:apply-templates select="page/pageArticles"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="pageArticles[not(has-children())]">
      <page>
          <number>{../@number}</number>
          <articleID/>
      </page>
  </xsl:template>

  <xsl:template match="articleID">
      <page>
          <number>{../../@number}</number>
          <articleID>{@id}</articleID>
      </page>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bFDb2BT以上是XSLT 3.在早期版本的XSLT中,您必须将文本值模板(例如{../@number})替换为xsl:value-of(例如<xsl:value-of select="../@number"/>)以及带有[not(has-children())]的谓词[not(node()]