XSLT:多次复制对象 xml,同时递增属性和值

发布于 2024-09-03 23:46:30 字数 4282 浏览 4 评论 0原文

我有一个如下所示的 xml,我想复制 n 次,同时递增其元素之一和属性之一。

XML 输入:

<?xml version="1.0"?>
<header xmlns="http://test.com" >
<Batch>
<test document="dump" >
<Person position=1>
    <properties>
        <name>John</name>
        <number>1</number>
    </properties>
</Person>
</test>
</Batch>
</header>

我想要像下面这样的内容,其中增量数是一个变量。

XML 输出:

<?xml version="1.0"?>
<header xmlns="http://test.com" >
<Batch>
<test document="dump" >
<Person position=1>
    <properties>
        <name>John</name>
        <number>1</number>
    </properties>
</Person>
<Person position=2>
    <properties>
        <name>John</name>
        <number>2</number>
    </properties>
</Person>
...
<Person position=n>
    <properties>
        <name>John</name>
        <number>n</number>
    </properties>
</Person>
</test>
</Batch>
</header>

为了解决这个问题,我从下面的 xslt 开始:

 <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:param name="pTimes" select="2"/>


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

 <xsl:template match="/*">
     <xsl:call-template name="applyNTimes">
         <xsl:with-param name="pTimes" select="$pTimes"/>
         <xsl:with-param name="pPosition" select="1"/>
     </xsl:call-template>
 </xsl:template>

 <xsl:template name="applyNTimes">
     <xsl:param name="pTimes" select="0"/>
     <xsl:param name="pPosition" select="1"/>

     <xsl:if test="$pTimes > 0">
         <xsl:choose>
         <xsl:when test="$pTimes = 1">
             <xsl:apply-templates select="*">
             <xsl:with-param name="pPosition" select="$pPosition"/>
             </xsl:apply-templates>
         </xsl:when>
         <xsl:otherwise>
             <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>

             <xsl:call-template name="applyNTimes">
             <xsl:with-param name="pTimes" select="$vHalf"/>
             <xsl:with-param name="pPosition" select="$pPosition"/>
             </xsl:call-template>

             <xsl:call-template name="applyNTimes">
             <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
             <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
             </xsl:call-template>
         </xsl:otherwise>
         </xsl:choose>
     </xsl:if>
 </xsl:template>

 <xsl:template match="Person">
     <xsl:param name="pPosition" select="1"/>

     <xsl:value-of select="$newline"/>
     <Person position="{$pPosition}">
         <xsl:apply-templates>
         <xsl:with-param name="pPosition" select="$pPosition"/>
         </xsl:apply-templates>
      </Person>
 </xsl:template>

 <xsl:template match="number">
      <xsl:param name="pPosition" select="1"/>

      <number><xsl:value-of select="$pPosition"/></number>
 </xsl:template>

 </xsl:stylesheet>

但输出包括元素中的名称空间。元素和属性 @position 始终设置为 1。此外,标题包围每个元素。 请参考下面 n=2 的输出

<Batch xmlns="http://test.com">
<test document="dump">
<Person position="1">
    <properties>
        <name>John</name>
        <number>1</number>
    </properties>
</Person>
</test>
</Batch>
<Batch xmlns="http://test.com">
<test document="dump">
    <Person position="1">
        <properties>
            <name>John</name>
            <number>1</number>
        </properties>
    </Person>
</test>
</Batch>

有任何线索吗?

I have a xml as below that I'd like to copy n times while incrementing one of its element and one of its attribute.

XML input:

<?xml version="1.0"?>
<header xmlns="http://test.com" >
<Batch>
<test document="dump" >
<Person position=1>
    <properties>
        <name>John</name>
        <number>1</number>
    </properties>
</Person>
</test>
</Batch>
</header>

and I'd like something like below with the number of increment to be a variable.

XML output:

<?xml version="1.0"?>
<header xmlns="http://test.com" >
<Batch>
<test document="dump" >
<Person position=1>
    <properties>
        <name>John</name>
        <number>1</number>
    </properties>
</Person>
<Person position=2>
    <properties>
        <name>John</name>
        <number>2</number>
    </properties>
</Person>
...
<Person position=n>
    <properties>
        <name>John</name>
        <number>n</number>
    </properties>
</Person>
</test>
</Batch>
</header>

To solve this, I've started with the xslt below:

 <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:param name="pTimes" select="2"/>


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

 <xsl:template match="/*">
     <xsl:call-template name="applyNTimes">
         <xsl:with-param name="pTimes" select="$pTimes"/>
         <xsl:with-param name="pPosition" select="1"/>
     </xsl:call-template>
 </xsl:template>

 <xsl:template name="applyNTimes">
     <xsl:param name="pTimes" select="0"/>
     <xsl:param name="pPosition" select="1"/>

     <xsl:if test="$pTimes > 0">
         <xsl:choose>
         <xsl:when test="$pTimes = 1">
             <xsl:apply-templates select="*">
             <xsl:with-param name="pPosition" select="$pPosition"/>
             </xsl:apply-templates>
         </xsl:when>
         <xsl:otherwise>
             <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>

             <xsl:call-template name="applyNTimes">
             <xsl:with-param name="pTimes" select="$vHalf"/>
             <xsl:with-param name="pPosition" select="$pPosition"/>
             </xsl:call-template>

             <xsl:call-template name="applyNTimes">
             <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
             <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
             </xsl:call-template>
         </xsl:otherwise>
         </xsl:choose>
     </xsl:if>
 </xsl:template>

 <xsl:template match="Person">
     <xsl:param name="pPosition" select="1"/>

     <xsl:value-of select="$newline"/>
     <Person position="{$pPosition}">
         <xsl:apply-templates>
         <xsl:with-param name="pPosition" select="$pPosition"/>
         </xsl:apply-templates>
      </Person>
 </xsl:template>

 <xsl:template match="number">
      <xsl:param name="pPosition" select="1"/>

      <number><xsl:value-of select="$pPosition"/></number>
 </xsl:template>

 </xsl:stylesheet>

but the output includes the namespace in elements. The element and attribute @position are always set to 1. Also, the header surrounds each element.
Please refer to the output below with n=2

<Batch xmlns="http://test.com">
<test document="dump">
<Person position="1">
    <properties>
        <name>John</name>
        <number>1</number>
    </properties>
</Person>
</test>
</Batch>
<Batch xmlns="http://test.com">
<test document="dump">
    <Person position="1">
        <properties>
            <name>John</name>
            <number>1</number>
        </properties>
    </Person>
</test>
</Batch>

Any clue?

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

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

发布评论

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

评论(2

邮友 2024-09-10 23:46:30

此转换:

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

     <xsl:param name="pTimes" select="2"/>

     <xsl:template match="node()|@*">
      <xsl:param name="pPosition" select="1"/>
      <xsl:copy>
       <xsl:apply-templates select="node()|@*">
         <xsl:with-param name="pPosition" select="$pPosition"/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>

     <xsl:template match="t:test">
         <xsl:call-template name="applyNTimes">
             <xsl:with-param name="pTimes" select="$pTimes"/>
             <xsl:with-param name="pPosition" select="1"/>
         </xsl:call-template>
     </xsl:template>

     <xsl:template name="applyNTimes">
         <xsl:param name="pTimes" select="0"/>
         <xsl:param name="pPosition" select="1"/>

         <xsl:if test="$pTimes > 0">
             <xsl:choose>
             <xsl:when test="$pTimes = 1">
                 <xsl:apply-templates select="*">
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:apply-templates>
             </xsl:when>
             <xsl:otherwise>
                 <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>

                 <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$vHalf"/>
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:call-template>

                 <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
                 <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
                 </xsl:call-template>
             </xsl:otherwise>
             </xsl:choose>
         </xsl:if>
     </xsl:template>

     <xsl:template match="t:Person">
         <xsl:param name="pPosition" select="1"/>

         <xsl:copy>
             <xsl:copy-of select="@*"/>
             <xsl:attribute name="position">
              <xsl:value-of select="$pPosition"/>
             </xsl:attribute>
             <xsl:apply-templates>
             <xsl:with-param name="pPosition" select="$pPosition"/>
             </xsl:apply-templates>
          </xsl:copy>
     </xsl:template>

     <xsl:template match="t:number">
          <xsl:param name="pPosition" select="1"/>
            <xsl:copy>
              <xsl:value-of select="$pPosition"/>
            </xsl:copy>
     </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时

<header xmlns="http://test.com" >
    <Batch>
        <test document="dump" >
            <Person position="1">
                <properties>
                    <name>John</name>
                    <number>1</number>
                </properties>
            </Person>
        </test>
    </Batch>
</header>

产生所需的结果

<header xmlns="http://test.com">
    <Batch>
        <Person position="1">
            <properties>
                <name>John</name>
                <number>1</number>
            </properties>
        </Person>
        <Person position="2">
            <properties>
                <name>John</name>
                <number>2</number>
            </properties>
        </Person>
    </Batch>
</header>

This transformation:

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

     <xsl:param name="pTimes" select="2"/>

     <xsl:template match="node()|@*">
      <xsl:param name="pPosition" select="1"/>
      <xsl:copy>
       <xsl:apply-templates select="node()|@*">
         <xsl:with-param name="pPosition" select="$pPosition"/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>

     <xsl:template match="t:test">
         <xsl:call-template name="applyNTimes">
             <xsl:with-param name="pTimes" select="$pTimes"/>
             <xsl:with-param name="pPosition" select="1"/>
         </xsl:call-template>
     </xsl:template>

     <xsl:template name="applyNTimes">
         <xsl:param name="pTimes" select="0"/>
         <xsl:param name="pPosition" select="1"/>

         <xsl:if test="$pTimes > 0">
             <xsl:choose>
             <xsl:when test="$pTimes = 1">
                 <xsl:apply-templates select="*">
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:apply-templates>
             </xsl:when>
             <xsl:otherwise>
                 <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>

                 <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$vHalf"/>
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:call-template>

                 <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
                 <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
                 </xsl:call-template>
             </xsl:otherwise>
             </xsl:choose>
         </xsl:if>
     </xsl:template>

     <xsl:template match="t:Person">
         <xsl:param name="pPosition" select="1"/>

         <xsl:copy>
             <xsl:copy-of select="@*"/>
             <xsl:attribute name="position">
              <xsl:value-of select="$pPosition"/>
             </xsl:attribute>
             <xsl:apply-templates>
             <xsl:with-param name="pPosition" select="$pPosition"/>
             </xsl:apply-templates>
          </xsl:copy>
     </xsl:template>

     <xsl:template match="t:number">
          <xsl:param name="pPosition" select="1"/>
            <xsl:copy>
              <xsl:value-of select="$pPosition"/>
            </xsl:copy>
     </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<header xmlns="http://test.com" >
    <Batch>
        <test document="dump" >
            <Person position="1">
                <properties>
                    <name>John</name>
                    <number>1</number>
                </properties>
            </Person>
        </test>
    </Batch>
</header>

produces the wanted results:

<header xmlns="http://test.com">
    <Batch>
        <Person position="1">
            <properties>
                <name>John</name>
                <number>1</number>
            </properties>
        </Person>
        <Person position="2">
            <properties>
                <name>John</name>
                <number>2</number>
            </properties>
        </Person>
    </Batch>
</header>
小矜持 2024-09-10 23:46:30
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:t="http://test.com">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
     <xsl:param name="pTimes" select="2"/>
     <xsl:template match="node()|@*">
      <xsl:param name="pPosition" select="1"/>
      <xsl:copy>
       <xsl:apply-templates select="node()|@*">
         <xsl:with-param name="pPosition" select="$pPosition"/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>
     <xsl:template match="t:test">
         <xsl:call-template name="applyNTimes">
             <xsl:with-param name="pTimes" select="$pTimes"/>
             <xsl:with-param name="pPosition" select="1"/>
         </xsl:call-template>
     </xsl:template>
     <xsl:template name="applyNTimes">
         <xsl:param name="pTimes" select="0"/>
         <xsl:param name="pPosition" select="1"/>
         <xsl:if test="$pTimes > 0">
             <xsl:choose>`enter code here`
             <xsl:when test="$pTimes = 1">
                 <xsl:apply-templates select="*">
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:apply-templates>
             </xsl:when>
             <xsl:otherwise>
                 <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>
                 <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$vHalf"/>
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:call-template>
                 <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
                 <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
                 </xsl:call-template>
             </xsl:otherwise>
             </xsl:choose>
         </xsl:if>
     </xsl:template>
     <xsl:template match="t:Person">
         <xsl:param name="pPosition" select="1"/>
         <xsl:copy>
             <xsl:copy-of select="@*"/>
             <xsl:attribute name="position">
              <xsl:value-of select="$pPosition"/>
             </xsl:attribute>
             <xsl:apply-templates>
             <xsl:with-param name="pPosition" select="$pPosition"/>
             </xsl:apply-templates>
          </xsl:copy>
     </xsl:template>
     <xsl:template match="t:number">
          <xsl:param name="pPosition" select="1"/>
            <xsl:copy>
              <xsl:value-of select="$pPosition"/>
            </xsl:copy>
     </xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:t="http://test.com">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
     <xsl:param name="pTimes" select="2"/>
     <xsl:template match="node()|@*">
      <xsl:param name="pPosition" select="1"/>
      <xsl:copy>
       <xsl:apply-templates select="node()|@*">
         <xsl:with-param name="pPosition" select="$pPosition"/>
       </xsl:apply-templates>
      </xsl:copy>
     </xsl:template>
     <xsl:template match="t:test">
         <xsl:call-template name="applyNTimes">
             <xsl:with-param name="pTimes" select="$pTimes"/>
             <xsl:with-param name="pPosition" select="1"/>
         </xsl:call-template>
     </xsl:template>
     <xsl:template name="applyNTimes">
         <xsl:param name="pTimes" select="0"/>
         <xsl:param name="pPosition" select="1"/>
         <xsl:if test="$pTimes > 0">
             <xsl:choose>`enter code here`
             <xsl:when test="$pTimes = 1">
                 <xsl:apply-templates select="*">
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:apply-templates>
             </xsl:when>
             <xsl:otherwise>
                 <xsl:variable name="vHalf" select="floor($pTimes div 2)"/>
                 <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$vHalf"/>
                 <xsl:with-param name="pPosition" select="$pPosition"/>
                 </xsl:call-template>
                 <xsl:call-template name="applyNTimes">
                 <xsl:with-param name="pTimes" select="$pTimes - $vHalf"/>
                 <xsl:with-param name="pPosition" select="$pPosition + $vHalf"/>
                 </xsl:call-template>
             </xsl:otherwise>
             </xsl:choose>
         </xsl:if>
     </xsl:template>
     <xsl:template match="t:Person">
         <xsl:param name="pPosition" select="1"/>
         <xsl:copy>
             <xsl:copy-of select="@*"/>
             <xsl:attribute name="position">
              <xsl:value-of select="$pPosition"/>
             </xsl:attribute>
             <xsl:apply-templates>
             <xsl:with-param name="pPosition" select="$pPosition"/>
             </xsl:apply-templates>
          </xsl:copy>
     </xsl:template>
     <xsl:template match="t:number">
          <xsl:param name="pPosition" select="1"/>
            <xsl:copy>
              <xsl:value-of select="$pPosition"/>
            </xsl:copy>
     </xsl:template>
</xsl:stylesheet>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文