xsl 1.0 用逗号分隔的项目进行分组

发布于 2024-12-11 22:24:27 字数 1138 浏览 0 评论 0原文

类似的 XML

<profiles>
<profile>
  <customer>customer a </customer>
  <collateral>
    <summary>summary a</summary>
   <related>
     <solutions>sol1,sol2</solutions>
   </related>
  <collateral>
</profile>
<profile>
  <customer>customer b </customer>
  <collateral>
    <summary>summary b</summary>
   <related>
     <solutions>sol1</solutions>
   </related>
  <collateral>
</profile>

<profile>
  <customer>customer c </customer>
  <collateral>
    <summary>summary c</summary>
   <related>
     <solutions>sol2,sol3</solutions>
   </related>
  <collateral>
</profile>
</profiles>

我有一个与此所需输出

<div id="#sol1">
  customer a,summary a
 customer b, summary b
</div>

<div id="#sol2">
  customer a,summary a
  customer c,summary c
</div>

......

我知道 Muenchian 的分组方式,但不确定如果我有逗号分隔的 groub-by 元素值,我该如何完成。任何帮助将不胜感激。

I have a XML similar to this

<profiles>
<profile>
  <customer>customer a </customer>
  <collateral>
    <summary>summary a</summary>
   <related>
     <solutions>sol1,sol2</solutions>
   </related>
  <collateral>
</profile>
<profile>
  <customer>customer b </customer>
  <collateral>
    <summary>summary b</summary>
   <related>
     <solutions>sol1</solutions>
   </related>
  <collateral>
</profile>

<profile>
  <customer>customer c </customer>
  <collateral>
    <summary>summary c</summary>
   <related>
     <solutions>sol2,sol3</solutions>
   </related>
  <collateral>
</profile>
</profiles>

Desired output

<div id="#sol1">
  customer a,summary a
 customer b, summary b
</div>

<div id="#sol2">
  customer a,summary a
  customer c,summary c
</div>

..............

Iam aware of Muenchian way of grouping, but not sure how I can accomplish, if I have comma separated groub-by element values. Any help will be appreciated.

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

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

发布评论

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

评论(1

掌心的温暖 2024-12-18 22:24:27

虽然这在 XSLT 2.0 中很简单,但在 XSLT 中,两遍转换可以产生所需的结果

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kSolByVal" match="solution" use="."/>

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

 <xsl:template match="/">
  <xsl:variable name="vrtfPass1">
   <xsl:apply-templates/>
  </xsl:variable>

  <xsl:apply-templates select=
  "ext:node-set($vrtfPass1)
                /*/*/*/*
                   /solutions/solution
                    [generate-id()
                    =
                    generate-id(key('kSolByVal', .)[1])
                    ]"
   mode="pass2"/>
 </xsl:template>

 <xsl:template mode="pass2" match="solution">
  <div id="#{.}">
    <xsl:apply-templates mode="pass2"
       select="key('kSolByVal', .)/../../../.."/>
  </div>
 </xsl:template>

 <xsl:template match="profile" mode="pass2">
  <xsl:if test="position() = 1">
   <xsl:text>
</xsl:text>
  </xsl:if>
  <xsl:value-of select=
      "concat(customer, ', ', */summary, '
')"/>
 </xsl:template>

 <xsl:template match="solutions">
   <solutions>
     <xsl:apply-templates select="." mode="split"/>
   </solutions>
 </xsl:template>

  <xsl:template match="solutions" name="split" mode="split">
   <xsl:param name="pText" select="."/>

   <xsl:if test="string-length($pText)">
    <xsl:variable name="vText1"
         select="concat($pText, ',')"/>
    <xsl:variable name="vPart" select=
       "substring-before($vText1, ',')"/>

     <solution>
      <xsl:value-of select="$vPart"/>
     </solution>

     <xsl:call-template name="split">
      <xsl:with-param name="pText"
           select="substring($pText, string-length($vPart)+2)"/>
     </xsl:call-template>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时(针对格式良好):

<profiles>
    <profile>
        <customer>customer a </customer>
        <collateral>
            <summary>summary a</summary>
            <related>
                <solutions>sol1,sol2</solutions>
            </related>
        </collateral>
    </profile>
    <profile>
        <customer>customer b </customer>
        <collateral>
            <summary>summary b</summary>
            <related>
                <solutions>sol1</solutions>
            </related>
        </collateral>
    </profile>
    <profile>
        <customer>customer c </customer>
        <collateral>
            <summary>summary c</summary>
            <related>
                <solutions>sol2,sol3</solutions>
            </related>
        </collateral>
    </profile>
</profiles>

产生了想要的正确结果

<div id="#sol1">
customer a , summary a
customer b , summary b
</div>
<div id="#sol2">
customer a , summary a
customer c , summary c
</div>
<div id="#sol3">
customer c , summary c
</div>

解释

  1. 我们分两遍进行转换。 Pass2 应用于对所提供的 XML 文档应用 Pass1 的结果。

  2. Pass 1 本质上是为任何 solutions 元素覆盖的身份规则。 solutions 元素的处理包括对其字符串值的递归分割。 Pass1 的最终结果如下:

--

<profiles>
   <profile>
      <customer>customer a </customer>
      <collateral>
         <summary>summary a</summary>
         <related>
            <solutions>
               <solution>sol1</solution>
               <solution>sol2</solution>
            </solutions>
         </related>
      </collateral>
   </profile>
   <profile>
      <customer>customer b </customer>
      <collateral>
         <summary>summary b</summary>
         <related>
            <solutions>
               <solution>sol1</solution>
            </solutions>
         </related>
      </collateral>
   </profile>
   <profile>
      <customer>customer c </customer>
      <collateral>
         <summary>summary c</summary>
         <related>
            <solutions>
               <solution>sol2</solution>
               <solution>sol3</solution>
            </solutions>
         </related>
      </collateral>
   </profile>
</profiles>

.3。然后,我们对 Pass1 的结果应用模板(在 mode="pass2" 中)。这是典型的传统慕尼黑团体。

While this is straight-forward in XSLT 2.0, in XSLT a two-pass transformation can produce the wanted results:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kSolByVal" match="solution" use="."/>

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

 <xsl:template match="/">
  <xsl:variable name="vrtfPass1">
   <xsl:apply-templates/>
  </xsl:variable>

  <xsl:apply-templates select=
  "ext:node-set($vrtfPass1)
                /*/*/*/*
                   /solutions/solution
                    [generate-id()
                    =
                    generate-id(key('kSolByVal', .)[1])
                    ]"
   mode="pass2"/>
 </xsl:template>

 <xsl:template mode="pass2" match="solution">
  <div id="#{.}">
    <xsl:apply-templates mode="pass2"
       select="key('kSolByVal', .)/../../../.."/>
  </div>
 </xsl:template>

 <xsl:template match="profile" mode="pass2">
  <xsl:if test="position() = 1">
   <xsl:text>
</xsl:text>
  </xsl:if>
  <xsl:value-of select=
      "concat(customer, ', ', */summary, '
')"/>
 </xsl:template>

 <xsl:template match="solutions">
   <solutions>
     <xsl:apply-templates select="." mode="split"/>
   </solutions>
 </xsl:template>

  <xsl:template match="solutions" name="split" mode="split">
   <xsl:param name="pText" select="."/>

   <xsl:if test="string-length($pText)">
    <xsl:variable name="vText1"
         select="concat($pText, ',')"/>
    <xsl:variable name="vPart" select=
       "substring-before($vText1, ',')"/>

     <solution>
      <xsl:value-of select="$vPart"/>
     </solution>

     <xsl:call-template name="split">
      <xsl:with-param name="pText"
           select="substring($pText, string-length($vPart)+2)"/>
     </xsl:call-template>
   </xsl:if>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document (corrected for well-formedness):

<profiles>
    <profile>
        <customer>customer a </customer>
        <collateral>
            <summary>summary a</summary>
            <related>
                <solutions>sol1,sol2</solutions>
            </related>
        </collateral>
    </profile>
    <profile>
        <customer>customer b </customer>
        <collateral>
            <summary>summary b</summary>
            <related>
                <solutions>sol1</solutions>
            </related>
        </collateral>
    </profile>
    <profile>
        <customer>customer c </customer>
        <collateral>
            <summary>summary c</summary>
            <related>
                <solutions>sol2,sol3</solutions>
            </related>
        </collateral>
    </profile>
</profiles>

the wanted, correct result is produced:

<div id="#sol1">
customer a , summary a
customer b , summary b
</div>
<div id="#sol2">
customer a , summary a
customer c , summary c
</div>
<div id="#sol3">
customer c , summary c
</div>

Explanation:

  1. We carry out the transformation in two passes. Pass2 is applied on the result of applying Pass1 on the provided XML document.

  2. Pass 1 is essentially the identity rule overriden for any solutions element. The processing of a solutions element consists in recursive splitting of its string value. The final result of Pass1 is the following:

--

<profiles>
   <profile>
      <customer>customer a </customer>
      <collateral>
         <summary>summary a</summary>
         <related>
            <solutions>
               <solution>sol1</solution>
               <solution>sol2</solution>
            </solutions>
         </related>
      </collateral>
   </profile>
   <profile>
      <customer>customer b </customer>
      <collateral>
         <summary>summary b</summary>
         <related>
            <solutions>
               <solution>sol1</solution>
            </solutions>
         </related>
      </collateral>
   </profile>
   <profile>
      <customer>customer c </customer>
      <collateral>
         <summary>summary c</summary>
         <related>
            <solutions>
               <solution>sol2</solution>
               <solution>sol3</solution>
            </solutions>
         </related>
      </collateral>
   </profile>
</profiles>

.3. We then apply templates (in mode="pass2") on the result of Pass1. This is a typical and traditional Muenchian grouping.

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