如何将xml节点与公共属性值合并

问题描述 投票:0回答:2

我想采用一些XML文档并合并具有相同属性值的某些级别的所有节点。例如,如果我有这种形式的文件,

<xml>
 <books id="X">
  <book name="Story"/>
  <book name="Tale"/>
 </books>
 <books id="X">
  <book name="Folklore"/>
  <book name="Magic"/>
 </books>
 <books id="Y">
  <book name="Harry Potter"/>
  <book name="LotR"/>
 </books>
</xml>

那么我希望能够将其转换为以下文档:

<xml>
 <books id="X">
  <book name="Story"/>
  <book name="Tale"/>
  <book name="Folklore"/>
  <book name="Magic"/>
 </books>
 <books id="Y">
  <book name="Harry Potter"/>
  <book name="LotR"/>
 </books>
</xml>

如果可能的话,我非常想要多种解决方案。例如,一个使用XSLT,另一个使用其他语言。

xml xslt xpath data-conversion
2个回答
0
投票

你可以试试这个:

<xsl:template match="xml">
        <xsl:for-each-group select="books" group-by="@id">
            <xsl:copy>
                <xsl:attribute name="id" select="current-grouping-key()"/>
                <xsl:apply-templates select="current-group()/*"/>
            </xsl:copy>
        </xsl:for-each-group>
    </xsl:template>

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

请参阅https://xsltfiddle.liberty-development.net/gWmuiJR的转换


0
投票
<xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="books[1][@id='X']">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
        <xsl:apply-templates/>
            <xsl:apply-templates select="following-sibling::books[@id='X']/book"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="books[@id='X' and preceding-sibling::books[@id='X']]"/>
    <xsl:template match="book">
        <xsl:copy>
        <xsl:apply-templates select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
check it.
© www.soinside.com 2019 - 2024. All rights reserved.