每个节点每个位置的 XSL 唯一值

发布于 2024-08-31 06:02:57 字数 3771 浏览 3 评论 0原文

这变得更加复杂:)

现在我在最后一个问题中面临另一个问题,我们

现在设法仅从一个父节点获取唯一值:

<?xml version="1.0" encoding="ISO-8859-1"?>
<roots>
     <root>
          <name>first</name>
          <item>
               <something>A</something>
               <something>A</something>
          </item>
          <item>
               <something>B</something>
               <something>A</something>
          </item>
          <item>
               <something>C</something>
               <something>P</something>
          </item>
          <item>
               <something>A</something>
               <something>L</something>
          </item>
          <item>
               <something>A</something>
               <something>A</something>
          </item>
          <item>
               <something>B</something>
               <something>A</something>
          </item>
          <item>
               <something>D</something>
               <something>A</something>
          </item>
     </root>
     <root>
          <name>second</name>
          <item>
               <something>E</something>
               <something>A</something>
          </item>
          <item>
               <something>B</something>
               <something>A</something>
          </item>
          <item>
               <something>F</something>
               <something>A</something>
          </item>
          <item>
               <something>A</something>
               <something>A</something>
          </item>
          <item>
               <something>A</something>
               <something>A</something>
          </item>
          <item>
               <something>B</something>
               <something>H</something>
          </item>
          <item>
               <something>D</something>
               <something>G</something>
          </item>
     </root>
</roots>

现在我需要获取仅依赖于之前的一个节点但仅依赖于父节点上的元素的唯一值 第二个位置

  <?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="yes" method="text"/>
  <xsl:key name="item-by-value" match="something"
 use="concat(normalize-space(.), ' ', generate-id(./ancestor::root))"/>
<xsl:key name="rootkey" match="root" use="name"/>
  <xsl:template match="/">
 <xsl:for-each select="key('rootkey','first')">
<xsl:for-each select="item/something[1]">
<xsl:sort />
  <xsl:if test="generate-id() = generate-id(key('item-by-value', 
                  concat(normalize-space(.), ' ', generate-id(./ancestor::root))))">
  <xsl:value-of select="."/>
 </xsl:if>
</xsl:for-each> 
<xsl:text>_________</xsl:text>
<xsl:for-each select="item/something[2]">
<xsl:sort />
  <xsl:if test="generate-id() = generate-id(key('item-by-value', 
                  concat(normalize-space(.), ' ', generate-id(./ancestor::root))))">
  <xsl:value-of select="."/>
 </xsl:if>
</xsl:for-each> 
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

这个 XSL 的 我得到 ABCD_________LP 我需要的结果是 ABCD_________ALP

有什么想法吗?

this get ever more complicated :)

now i face another issue in last question we managed to take unique values from only one parent node

now with:

<?xml version="1.0" encoding="ISO-8859-1"?>
<roots>
     <root>
          <name>first</name>
          <item>
               <something>A</something>
               <something>A</something>
          </item>
          <item>
               <something>B</something>
               <something>A</something>
          </item>
          <item>
               <something>C</something>
               <something>P</something>
          </item>
          <item>
               <something>A</something>
               <something>L</something>
          </item>
          <item>
               <something>A</something>
               <something>A</something>
          </item>
          <item>
               <something>B</something>
               <something>A</something>
          </item>
          <item>
               <something>D</something>
               <something>A</something>
          </item>
     </root>
     <root>
          <name>second</name>
          <item>
               <something>E</something>
               <something>A</something>
          </item>
          <item>
               <something>B</something>
               <something>A</something>
          </item>
          <item>
               <something>F</something>
               <something>A</something>
          </item>
          <item>
               <something>A</something>
               <something>A</something>
          </item>
          <item>
               <something>A</something>
               <something>A</something>
          </item>
          <item>
               <something>B</something>
               <something>H</something>
          </item>
          <item>
               <something>D</something>
               <something>G</something>
          </item>
     </root>
</roots>

now i need to get the unique values depending only from one node before but just from the elements on the second position

  <?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="yes" method="text"/>
  <xsl:key name="item-by-value" match="something"
 use="concat(normalize-space(.), ' ', generate-id(./ancestor::root))"/>
<xsl:key name="rootkey" match="root" use="name"/>
  <xsl:template match="/">
 <xsl:for-each select="key('rootkey','first')">
<xsl:for-each select="item/something[1]">
<xsl:sort />
  <xsl:if test="generate-id() = generate-id(key('item-by-value', 
                  concat(normalize-space(.), ' ', generate-id(./ancestor::root))))">
  <xsl:value-of select="."/>
 </xsl:if>
</xsl:for-each> 
<xsl:text>_________</xsl:text>
<xsl:for-each select="item/something[2]">
<xsl:sort />
  <xsl:if test="generate-id() = generate-id(key('item-by-value', 
                  concat(normalize-space(.), ' ', generate-id(./ancestor::root))))">
  <xsl:value-of select="."/>
 </xsl:if>
</xsl:for-each> 
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

with this XSL i get ABCD_________LP
where the result i need is ABCD_________ALP

any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一个人的旅程 2024-09-07 06:02:57

再次,问题是,如果您想说“此根下具有此内容的第一个节点出现在item节点中的这个位置”,那么您必须将“在 item 节点中的位置”添加到键中。您可以通过使用两个单独的键来实现此目的,如 Dimitre 的解决方案所做的那样,或者将键更改为:

use="concat(normalize-space(.), ' ', 
     count(./preceding-sibling::something), ' ', generate-id(./ancestor::root))"/>

然后使两个测试表达式如下所示:

<xsl:if test="generate-id() = generate-id(key('item-by-value', 
              concat(normalize-space(.), ' 0 ', generate-id(./ancestor::root))))">

和:

<xsl:if test="generate-id() = generate-id(key('item-by-value', 
              concat(normalize-space(.), ' 1 ', generate-id(./ancestor::root))))">

Once again, the issue is that if you want to say "the first node with this content under this root appearing in this position in the item node", then you have to add "position in the item node" to the key. You can either do this by having two separate keys, as Dimitre's solution does, or change your key to:

use="concat(normalize-space(.), ' ', 
     count(./preceding-sibling::something), ' ', generate-id(./ancestor::root))"/>

And then make your two test expressions look like:

<xsl:if test="generate-id() = generate-id(key('item-by-value', 
              concat(normalize-space(.), ' 0 ', generate-id(./ancestor::root))))">

and:

<xsl:if test="generate-id() = generate-id(key('item-by-value', 
              concat(normalize-space(.), ' 1 ', generate-id(./ancestor::root))))">
等待我真够勒 2024-09-07 06:02:57

只需对我对您之前问题的回答稍加修改即可!

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

 <xsl:key name="kSomethingByNameAndVal-1" match="something[1]"
  use="concat(../../name, '+', .)"/>

 <xsl:key name="kSomethingByNameAndVal-2" match="something[2]"
  use="concat(../../name, '+', .)"/>

 <xsl:template match="/">
   <xsl:for-each select="*/*">
     <xsl:for-each select=
      "item/something[1]
             [generate-id()
             =
              generate-id(key('kSomethingByNameAndVal-1',
                               concat(../../name, '+', .)
                              )
                          )
             ]
      ">

       <xsl:value-of select="."/>
     </xsl:for-each>
     <xsl:text>
</xsl:text>

     <xsl:for-each select=
      "item/something[2]
             [generate-id()
             =
              generate-id(key('kSomethingByNameAndVal-2',
                               concat(../../name, '+', .)
                              )
                          )
             ]
      ">

       <xsl:value-of select="."/>
     </xsl:for-each>
     <xsl:text>
</xsl:text>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时,就会产生所需的正确结果 :

ABCD
APL
EBFAD
AHG

Just a slight modification to my answer to your previous question and you've got it!

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

 <xsl:key name="kSomethingByNameAndVal-1" match="something[1]"
  use="concat(../../name, '+', .)"/>

 <xsl:key name="kSomethingByNameAndVal-2" match="something[2]"
  use="concat(../../name, '+', .)"/>

 <xsl:template match="/">
   <xsl:for-each select="*/*">
     <xsl:for-each select=
      "item/something[1]
             [generate-id()
             =
              generate-id(key('kSomethingByNameAndVal-1',
                               concat(../../name, '+', .)
                              )
                          )
             ]
      ">

       <xsl:value-of select="."/>
     </xsl:for-each>
     <xsl:text>
</xsl:text>

     <xsl:for-each select=
      "item/something[2]
             [generate-id()
             =
              generate-id(key('kSomethingByNameAndVal-2',
                               concat(../../name, '+', .)
                              )
                          )
             ]
      ">

       <xsl:value-of select="."/>
     </xsl:for-each>
     <xsl:text>
</xsl:text>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document, The wanted, correct results are produced:

ABCD
APL
EBFAD
AHG
尘世孤行 2024-09-07 06:02:57

我知道您仅限于 XSLT 1.0 并且您正在使用 Xalan,但我将添加此答案,以防万一它可以帮助其他人将来进行搜索。 (那可以使用XSLT 2.0。)希望你不介意。

另外,我使用 Saxon-HE 9.2.0.6 作为处理器。

这是样式表:

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

   <xsl:template match="/roots">
      <xsl:for-each select="root">
         <xsl:value-of select="distinct-values(item/something[1])"/>___<xsl:value-of select="distinct-values(item/something[2])"/>
         <xsl:text>
</xsl:text>
      </xsl:for-each>
   </xsl:template>

</xsl:stylesheet>

这是使用 XML 的输出:

A B C D___A P L
E B F A D___A H G

如果您想从输出中删除空格,您可以将输出放入变量中,然后使用 replace 删除空格。 (有人知道更好的方法吗?)

样式表:

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

   <xsl:template match="/roots">
      <xsl:variable name="output">
         <xsl:for-each select="root">
            <xsl:value-of select="distinct-values(item/something[1])"/>___<xsl:value-of select="distinct-values(item/something[2])"/>
            <xsl:text>
</xsl:text>
         </xsl:for-each>
      </xsl:variable>
      <xsl:value-of select="replace($output,' ','')"/>
   </xsl:template>

</xsl:stylesheet>

输出:

ABCD___APL
EBFAD___AHG

I know you're restricted to XSLT 1.0 and you're using Xalan, but I'm going to add this answer just in case it might help someone else doing a search in the future. (That can use XSLT 2.0.) Hope you don't mind.

Also, I'm using Saxon-HE 9.2.0.6 for the processor.

Here's the stylesheet:

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

   <xsl:template match="/roots">
      <xsl:for-each select="root">
         <xsl:value-of select="distinct-values(item/something[1])"/>___<xsl:value-of select="distinct-values(item/something[2])"/>
         <xsl:text>
</xsl:text>
      </xsl:for-each>
   </xsl:template>

</xsl:stylesheet>

Here's the output using your XML:

A B C D___A P L
E B F A D___A H G

If you wanted to strip the spaces from the output, you could put the output in a variable and then use replace to strip the spaces. (Anyone know of a better way?)

Stylesheet:

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

   <xsl:template match="/roots">
      <xsl:variable name="output">
         <xsl:for-each select="root">
            <xsl:value-of select="distinct-values(item/something[1])"/>___<xsl:value-of select="distinct-values(item/something[2])"/>
            <xsl:text>
</xsl:text>
         </xsl:for-each>
      </xsl:variable>
      <xsl:value-of select="replace($output,' ','')"/>
   </xsl:template>

</xsl:stylesheet>

Output:

ABCD___APL
EBFAD___AHG
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文