xsl获取原始父节点以及ParentID是该父节点的其他节点

时间:2016-02-15 08:22:17

标签: xml xslt

我有xml如下。使用xsl,我想获取节点(父节点和parentItem指向该特定父节点的所有其他节点)

<apis>
  <api>
     <name>myFirstApi</name>
     <itemNumber>1</itemNumber>
     <parentItem></parentItem>
     <parameter></parameter>
  </api>
   <api>
     <name>mySecondApi</name>
     <itemNumber>2</itemNumber>
     <parentItem>1</parentItem>
     <parameter>someparameter</parameter>
  </api>
  <api>
     <name>myThirdApi</name>
     <itemNumber>3</itemNumber>
     <parentItem></parentItem>
     <parameter></parameter>
  </api>
</apis>

对于上面的例子,我想获得第一个节点,它有itemNumber 1和第二个节点,因为第二个节点的parentItem指向节点1.

由于<parameter>节点不是api 1中的节点,但它在itemNumber 2中,其中parentItem为1,我想将itemNumber 2中的<parameter>值添加到itemNumber 1。

预期输出为:

  <apis>
  <api>
     <name>myFirstApi</name>
     <itemNumber>1</itemNumber>
     <parameter>someparameter</parameter>
  </api>
  <api>
     <name>myThirdApi</name>
     <itemNumber>3</itemNumber>
     <parentItem></parentItem>
     <parameter></parameter>
  </api>
</apis>

2 个答案:

答案 0 :(得分:0)

/apis/api[parentItem = '']会或多或少地产生您的预期输出。

答案 1 :(得分:0)

您应该在这里了解xsl:key,因为这样可以非常直接地查找元素中的节点。在您的情况下,您希望按api查找parentItem个元素,因此您可以像这样定义一个键:

<xsl:key name="parent" match="api" use="parentItem" />

然后,假设您被定位在父api元素上,您可以获得“child”api,就像这样

<xsl:apply-template select="key('parent', itemNumber)" />

但是,要解决您的特定示例,您可能希望从XSLT身份模板开始

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

您可以从父母选择api元素开始:

<xsl:apply-templates select="key('parent', '')"/>

然后,您只需要编写一个模板来更改任何空的parameter节点

<xsl:template match="parameter[. = '']">
    <xsl:copy>
        <xsl:value-of select="key('parent', ../itemNumber)/parameter" />
    </xsl:copy>
</xsl:template>

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:key name="parent" match="api" use="parentItem" />

    <xsl:template match="apis">
        <xsl:copy>
            <xsl:apply-templates select="key('parent', '')"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="parameter[. = '']">
        <xsl:copy>
            <xsl:value-of select="key('parent', ../itemNumber)/parameter" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>