如何使用 xslt 创建新列表并在其中标记节点

发布于 2024-11-03 14:27:17 字数 1607 浏览 1 评论 0原文

我正在使用身份转换将一个 XML 转换为另一个 XML,在此期间,根据我想要在新列表中标记几个节点的条件。 假设我有一个像这样的 XML:
<点头>
        A
       B
       

p1


       

p2


       

p3


       

p4


在此 XML 中,我想将 'nod' 的名称更新为 'newnod' 并为元素 'c' 创建一个有序列表;因此输出如下:

        A
       B
        <有序列表>
                   ;       <列表项>

p1


              ;           <列表项>

p2


             ;           <列表项>

p3


             ;          

p4


        

有人可以告诉我该怎么做吗?

谢谢 !!!

I am transforming an XML to another using Identity Transformation and during this, based on a condition I want to tag few nodes in a new list.
Suppose, I have an XML like:

<nod>
        
<a>A</a>
        
<b>B</b>
        
<c><p>p1</p></c>
        
<c><p>p2</p></c>
        
<c><p>p3</p></c>
        
<c><p>p4</p></c>
</nod>

From this XML , I want to update name of 'nod' to 'newnod' and create an orderedlist for element 'c' ; so that output comes as:

<newnod>
        
<a>A</a>
        
<b>B</b>
        
<orderedlist>
                            
<listitem><p>p1</p></listitem>
                            
<listitem><p>p2</p></listitem>
                            
<listitem><p>p3</p></listitem>
                            
<listitem><p>p4</p></listitem>
         </orderedlist>
</newnod>

Can anybody please tell me how to do this.

Thanks !!!

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

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

发布评论

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

评论(4

清风疏影 2024-11-10 14:27:17

这是一个真正的“推送式”解决方案:

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

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

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

 <xsl:template match="c[1]">
  <orderedlist>
   <xsl:apply-templates mode="wrap"
    select=".|following-sibling::c"/>
  </orderedlist>
 </xsl:template>

 <xsl:template match="c" mode="wrap">
  <listitem>
   <xsl:apply-templates/>
  </listitem>
 </xsl:template>

 <xsl:template match="c"/>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时

<nod>
 <a>A</a>
 <b>B</b>
 <c><p>p1</p></c>
 <c><p>p2</p></c>
 <c><p>p3</p></c>
 <c><p>p4</p></c>
</nod>

生成所需的正确结果 :

<newnod>
  <a>A</a>
  <b>B</b>
  <orderedlist>
    <listitem>
      <p>p1</p>
    </listitem>
    <listitem>
      <p>p2</p>
    </listitem>
    <listitem>
      <p>p3</p>
    </listitem>
    <listitem>
      <p>p4</p>
    </listitem>
  </orderedlist>
</newnod>

Here is a true "push-style" solution:

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

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

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

 <xsl:template match="c[1]">
  <orderedlist>
   <xsl:apply-templates mode="wrap"
    select=".|following-sibling::c"/>
  </orderedlist>
 </xsl:template>

 <xsl:template match="c" mode="wrap">
  <listitem>
   <xsl:apply-templates/>
  </listitem>
 </xsl:template>

 <xsl:template match="c"/>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<nod>
 <a>A</a>
 <b>B</b>
 <c><p>p1</p></c>
 <c><p>p2</p></c>
 <c><p>p3</p></c>
 <c><p>p4</p></c>
</nod>

the wanted, correct result is produced:

<newnod>
  <a>A</a>
  <b>B</b>
  <orderedlist>
    <listitem>
      <p>p1</p>
    </listitem>
    <listitem>
      <p>p2</p>
    </listitem>
    <listitem>
      <p>p3</p>
    </listitem>
    <listitem>
      <p>p4</p>
    </listitem>
  </orderedlist>
</newnod>
嘿看小鸭子会跑 2024-11-10 14:27:17

这会为您的示例生成所需的输出:

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

  <xsl:output indent="yes"/>

  <xsl:template match="/nod">
    <newnod>
      <xsl:copy-of select="*[not( self::c )]"/>
      <orderedlist>
        <xsl:apply-templates select="c">
          <xsl:sort/>
        </xsl:apply-templates>
      </orderedlist>
    </newnod>
  </xsl:template>

  <xsl:template match="nod/c">
    <listitem>
      <xsl:copy-of select="node()"/>
    </listitem>
  </xsl:template>

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

</xsl:stylesheet>

请注意,它可能需要针对您的实际输入进行一些调整。例如,排序的细节。或者abc的序列。是否将所有 c 集中在一起?但它适用于你的样本。

This produces the desired output for your example:

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

  <xsl:output indent="yes"/>

  <xsl:template match="/nod">
    <newnod>
      <xsl:copy-of select="*[not( self::c )]"/>
      <orderedlist>
        <xsl:apply-templates select="c">
          <xsl:sort/>
        </xsl:apply-templates>
      </orderedlist>
    </newnod>
  </xsl:template>

  <xsl:template match="nod/c">
    <listitem>
      <xsl:copy-of select="node()"/>
    </listitem>
  </xsl:template>

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

</xsl:stylesheet>

Note that it might need some tweaking for your actual input. For example, the details of sorting. Or the sequence of a, b and c. And lump all c together or not? But it works for your sample.

奢望 2024-11-10 14:27:17

你可以使用类似的东西:

<xsl:template match="nod">
    <newnod>
        <xsl:copy-of select="a"/>
        <xsl:copy-of select="b"/>
        <orderedlist>
            <xsl:for-each select="c">
                <listitem><p><xsl:value-of select="."/></p></listitem>
            </xsl:for-each>
        </orderedlist>
    </newnod>
</xsl:template>

You could use something like:

<xsl:template match="nod">
    <newnod>
        <xsl:copy-of select="a"/>
        <xsl:copy-of select="b"/>
        <orderedlist>
            <xsl:for-each select="c">
                <listitem><p><xsl:value-of select="."/></p></listitem>
            </xsl:for-each>
        </orderedlist>
    </newnod>
</xsl:template>
墨洒年华 2024-11-10 14:27:17

其他方法是像这样遍历以下轴:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="nod">
        <newnod>
            <xsl:apply-templates select="node()[1]|@*"/>
        </newnod>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="c">
        <orderedlist>
            <xsl:call-template name="wrap"/>
        </orderedlist>
        <xsl:apply-templates select="following-sibling::node()[1]"
                             mode="search"/>
    </xsl:template>
    <xsl:template match="c" name="wrap" mode="wrap">
        <listitem>
            <xsl:apply-templates select="node()[1]|@*"/>
        </listitem>
        <xsl:apply-templates select="following-sibling::node()[1]"
                             mode="wrap"/>
    </xsl:template>
    <xsl:template match="node()" mode="wrap"/>
    <xsl:template match="c" mode="search">
        <xsl:apply-templates select="following-sibling::node()[1]"
                             mode="search"/>
    </xsl:template>
    <xsl:template match="node()" mode="search">
        <xsl:apply-templates select="."/>
    </xsl:template>
</xsl:stylesheet>

或者更短(更多“推送样式”):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="nod">
        <newnod>
            <xsl:apply-templates select="node()[1]|@*"/>
        </newnod>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="c">
        <orderedlist>
            <xsl:call-template name="wrap"/>
        </orderedlist>
        <xsl:apply-templates select="following-sibling::node()
                                        [not(self::c)][1]"/>
    </xsl:template>
    <xsl:template match="c" name="wrap" mode="wrap">
        <listitem>
            <xsl:apply-templates select="node()[1]|@*"/>
        </listitem>
        <xsl:apply-templates select="following-sibling::node()[1]
                                        /self::c"
                             mode="wrap"/>
    </xsl:template>
</xsl:stylesheet>

两种输出:

<newnod>
    <a>A</a>
    <b>B</b>
    <orderedlist>
        <listitem>
            <p>p1</p>
        </listitem>
        <listitem>
            <p>p2</p>
        </listitem>
        <listitem>
            <p>p3</p>
        </listitem>
        <listitem>
            <p>p4</p>
        </listitem>
    </orderedlist>
</newnod>

注意:即使使用 XSLT 2.0,使用此模式也可以更好地表达一些复杂的序列处理。

Other approach is traversing the following axis like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="nod">
        <newnod>
            <xsl:apply-templates select="node()[1]|@*"/>
        </newnod>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="c">
        <orderedlist>
            <xsl:call-template name="wrap"/>
        </orderedlist>
        <xsl:apply-templates select="following-sibling::node()[1]"
                             mode="search"/>
    </xsl:template>
    <xsl:template match="c" name="wrap" mode="wrap">
        <listitem>
            <xsl:apply-templates select="node()[1]|@*"/>
        </listitem>
        <xsl:apply-templates select="following-sibling::node()[1]"
                             mode="wrap"/>
    </xsl:template>
    <xsl:template match="node()" mode="wrap"/>
    <xsl:template match="c" mode="search">
        <xsl:apply-templates select="following-sibling::node()[1]"
                             mode="search"/>
    </xsl:template>
    <xsl:template match="node()" mode="search">
        <xsl:apply-templates select="."/>
    </xsl:template>
</xsl:stylesheet>

Or shorter (more "push style"):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()[1]|@*"/>
        </xsl:copy>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="nod">
        <newnod>
            <xsl:apply-templates select="node()[1]|@*"/>
        </newnod>
        <xsl:apply-templates select="following-sibling::node()[1]"/>
    </xsl:template>
    <xsl:template match="c">
        <orderedlist>
            <xsl:call-template name="wrap"/>
        </orderedlist>
        <xsl:apply-templates select="following-sibling::node()
                                        [not(self::c)][1]"/>
    </xsl:template>
    <xsl:template match="c" name="wrap" mode="wrap">
        <listitem>
            <xsl:apply-templates select="node()[1]|@*"/>
        </listitem>
        <xsl:apply-templates select="following-sibling::node()[1]
                                        /self::c"
                             mode="wrap"/>
    </xsl:template>
</xsl:stylesheet>

Both output:

<newnod>
    <a>A</a>
    <b>B</b>
    <orderedlist>
        <listitem>
            <p>p1</p>
        </listitem>
        <listitem>
            <p>p2</p>
        </listitem>
        <listitem>
            <p>p3</p>
        </listitem>
        <listitem>
            <p>p4</p>
        </listitem>
    </orderedlist>
</newnod>

Note: Even with XSLT 2.0, some complex sequence processing are expressed better with this pattern.

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