使用 xslt 1.0 从两个不同的父标签中查找不同的元素

Posted

技术标签:

【中文标题】使用 xslt 1.0 从两个不同的父标签中查找不同的元素【英文标题】:finding distinct elements from two different parent tags using xslt 1.0 【发布时间】:2018-08-25 10:28:45 【问题描述】:

我试图从以下示例 XML 中仅使用 XSLT 1.0 从两个不同的父节点中查找不同的值。我需要的是一个模板,它通过将整体作为参数传递给每个<one> 节点来调用。 <vln> 标识每个 <one> 节点

输入:

   <?xml version="1.0" encoding="UTF-8"?>
   <filename>
     <root>
       <vln>56837073</vln>
       <one>
         <vln>1233213427</vln>
         <Maddress>
           <address>
             <state>ak</state>
           </address>
         </Maddress>
         <Maddress>
           <address>
             <state>vr</state>
           </address>
         </Maddress>
         <co>
           <Maddress>
             <address>
               <state>fg</state>
             </address>
           </Maddress>
           <Maddress>
             <address>
               <state>ak</state>
             </address>
           </Maddress>
         </co>
       </one>
       <one>
         <vln>6785475239</vln>
         <Maddress>
           <address>
             <state>pp</state>
           </address>
         </Maddress>
         <Maddress>
           <address>
             <state>fg</state>
           </address>
         </Maddress>
         <co>
           <Maddress>
             <address>
               <state>fg</state>
             </address>
           </Maddress>
           <Maddress>
             <address>
               <state>ak</state>
             </address>
           </Maddress>
         </co>
       </one>
     </root>
   </filename>

输出: 1.ak、vr、fg

2.pp, fg, ak

3....继续取决于&lt;one&gt; 节点的数量

我按照各种教程尝试了所有我理解的方法。我所取得的成就是使用http://www.jenitennison.com/xslt/grouping/muenchian.html 找到单个父级的不同值,但是当结合起来我不知道。帮我解决这个问题。

我的代码:

<xsl:key name="product" match="one/Maddress/address/state/text()" use="." />
<xsl:template match="one">
          <xsl:for-each select="one/Maddress/address/state/text()[generate-id() = generate-id(key('product',.)[1])]">
              <xsl:value-of select="."/>
              <text> </text>
          </xsl:for-each>

<xsl:key name="product2" match="one/co/Maddress/address/state/text()" use="." />        
<xsl:template match="two">
          <xsl:for-each select="one/co/Maddress/address/state/text()[generate-id() = generate-id(key('product2',.)[1])]">
              <xsl:value-of select="."/>
              <text> </text>
          </xsl:for-each>

这里调用一个和两个模板来检查来自两个不同父节点的不同值。 实现的输出:

1.ak、vr、fg、ak 2.pp, fg, fg, ak

【问题讨论】:

您能否编辑您的问题以显示您尝试过的内容?谢谢! 您的要求是文本格式吗? @AmrendraKumar,不是文本格式 我正在检查纯 HTML 格式的不同值,只是将 XML 简单转换为 HTML @TimC 这是我为从不同的父标签获取不同值所做的工作 【参考方案1】:

您正在尝试为每个 one 元素获取不同的状态。这意味着您需要使用连接键

<xsl:key name="product"  match="state" use="concat(ancestor::one/vln, '|', .)" />

这假设 vln 对于每个 one 节点都是唯一的。

然后,在每个 one 节点中,您会得到如下不同的状态:

<xsl:for-each select=".//state[generate-id() = generate-id(key('product', concat(ancestor::one/vln, '|', .))[1])]">

试试这个 XSLT

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

<xsl:output method="text" />
<xsl:key name="product"  match="state" use="concat(ancestor::one/vln, '|', .)" />

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

<xsl:template match="one">
  <xsl:value-of select="vln" />
    <xsl:text> </xsl:text>
    <xsl:for-each select=".//state[generate-id() = generate-id(key('product', concat(ancestor::one/vln, '|', .))[1])]">
      <xsl:value-of select="."/>
      <xsl:text> </xsl:text>
    </xsl:for-each>
  <xsl:text>&#10;</xsl:text>
</xsl:template>
</xsl:stylesheet>

【讨论】:

感谢您的回答,它确实有效我错过了这个祖先::one/vln 部分,只是写了 one/vln【参考方案2】:

如果您的要求是文本,那么您可以使用以下代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output method="text" />

    <xsl:template match="/">
        <xsl:value-of select="distinct-values(//state)" separator=", "/>
    </xsl:template>


</xsl:stylesheet>

【讨论】:

对不起,我的错误更不用说我只能使用 XSLT 1.0

以上是关于使用 xslt 1.0 从两个不同的父标签中查找不同的元素的主要内容,如果未能解决你的问题,请参考以下文章

xslt 1.0 使用复合键分组(在不同级别)

XSLT 如何从不同的标签级别访问属性?

如何使用 XSLT 从 XML 中删除元素标记

使用 XSLT 1.0 的逗号分隔子组和组

如何使用 xslt 更改单个标签?

如何在下面的 XSLT 1.0 代码中进行分组。需要按 TaxRateCode 分组