0

我想匹配节点属性值,如果相同的值出现在另一个节点属性中,我必须合并它们。所以例如我有一个xml

<xml>
   <title>
   <metadata>
    <ref cite="ABC" relevance="2"/>
    </metadata>
     <body>
       <para>
            <text>(some text from title)</text>
      </para>
     </body>
    </title>
    <title>
      <metadata>
         <ref cite="ABC" relevance="1"/>
      </metadata>
     <body>
       <para>
            <text>(some more text from title 2)</text>
      </para>
     </body>
    </title>

    <mainbody>
        <targetref cite="ABC"/>
        <text>This is a text</text>  
   </mainbody>
 </xml>

所以在转换后输出应该如下所示,所以基于元素标题/元数据/引用的引用“ABC”并按相关性排序(1,2 ....)标题的内容被合并到主体的文本元素中如果元素“targetref”的引用与元素“ref”的引用匹配

<xml>
  <mainbody>
    <targetref cite="ABC"/>
    <text>This is a text 
        <para><text>(some more text from title 2)</text></para>
       <para><text>(some text from title)</text></para> 
    </text>
   </mainbody>
 </xml> 

谢谢

4

2 回答 2

0

这里有一些 xslt 可以满足您的要求:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:output omit-xml-declaration="no" method="xml"/>
<xsl:strip-space elements="*"/>

<xsl:template match="mainbody">
<xsl:copy>
        <xsl:copy-of select="targetref"/>
        <xsl:element name="text">
            <xsl:value-of select="."/>
            <xsl:variable name="key" select="targetref/@cite"/>
            <xsl:for-each select="/xml/title[metadata/ref/@cite=$key]">
                <xsl:sort data-type="number" select="metadata/ref/@relevance" order="ascending" />
                <xsl:copy-of select="body/para"/>
            </xsl:for-each>
        </xsl:element>
    </xsl:copy>
</xsl:template>

<xsl:template match="xml/title"/>

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

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

</xsl:stylesheet>

技巧是在正常流程上忽略节点 xml/title,我们专注于主体标签,然后调用 for-each 来选择和排序所需的节点,并将信息写入主体内我们想要的位置。选择需要一个变量($key)来过滤主体上的指定

于 2012-05-18T18:32:24.367 回答
0

一种方法是通过键来根据元数据参考值查找标题记录:

<xsl:key name="ref" match="title" use="metadata/ref/@cite" />

然后,假设您位于主体内的文本元素上,您可以像这样查找它们,并同时对它们进行排序

<xsl:apply-templates select="key('ref', preceding-sibling::targetref/@cite)/body/para">
   <xsl:sort select="../../metadata/ref/@relevance" />

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="ref" match="title" use="metadata/ref/@cite" />
   <xsl:template match="title" />

  <xsl:template match="mainbody/text">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <xsl:apply-templates select="key('ref', preceding-sibling::targetref/@cite)/body/para" >
         <xsl:sort select="../../metadata/ref/@relevance" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

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

应用于您的示例 XML 时,将输出以下内容

<xml>
    <mainbody>
        <targetref cite="ABC"/>
        <text>This is a text
            <para>
                <text>(some more text from title 2)</text>
            </para>
            <para>
                <text>(some text from title)</text>
            </para></text>
    </mainbody>
</xml>
于 2012-05-18T18:47:46.540 回答