【问题标题】:How can I transform some xml into a fixed length string using element attributes to define the value lengths [duplicate]如何使用元素属性将一些xml转换为固定长度的字符串来定义值长度[重复]
【发布时间】:2020-10-09 05:58:51
【问题描述】:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
    <Destination>acme.com</Destination>
    <Record>
       <FirstField length="10">AAAA</FirstField>
       <SecondField length="15">BBBB</SecondField>
       <SubRecord>
          <ThirdField length="20">CCCC</ThirdField>
          <FourthField length="8">DDDD</FourthField>
       </SubRecord>
    </Record>
</Root>

您好,我需要使用这个 xml 示例,其中节点内的元素将是动态的,并且可以是几层深,并创建一个固定长度的文本字符串,其中每个值都被填充到左侧,使用一些可以处理 xml 直到完成的 xslt 转换。每个值的长度是在常量长度属性值中定义的,所以转换后的上述示例将是(在引号内,因此您可以看到全长字符串:

"      AAAA           BBBB                CCCC    DDDD"

我尝试了几次尝试创建所需的 xslt 来转换它,但运气不佳,因为我对 xslt 了解不够。

是否有人能够提供可能有用的东西。需要在 xsl 1.0 中。

谢谢。

【问题讨论】:

  • 我已经回滚了你的问题。您向new question 提出您的新要求是完全正确的。

标签: xml xslt attributes xslt-1.0


【解决方案1】:

试试这个:

<xsl:variable name="spaces" select="'                                   '"/>
   <xsl:template match="/">
       <xsl:text>"</xsl:text>
       <xsl:for-each select="//*[@length]">
           <xsl:variable name="spacelenght" select="@length - string-length(.)"/>
           <xsl:value-of select="concat(substring($spaces, 1, $spacelenght), .)"/>
       </xsl:for-each>
       <xsl:text>"</xsl:text>
   </xsl:template>
   

输出

"      AAAA           BBBB                CCCC    DDDD"

https://xsltfiddle.liberty-development.net/6q1S8AC查看转换

关于您更新的问题

<?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="1.0">

    <xsl:output method="text"/>

    <xsl:variable name="spaces" select="'                                   '"/>
    
    <xsl:template match="/">
        <xsl:text>"</xsl:text>
            <xsl:apply-templates/> 
        <xsl:text>"</xsl:text>
    </xsl:template>
    
    <xsl:template match="node()" priority="-1">
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match="*[@Occurs]">
    <xsl:variable name="data">
        <xsl:apply-templates/>
    </xsl:variable>
    <xsl:call-template name="copy">
        <xsl:with-param name="data" select="$data"/>
        <xsl:with-param name="seq" select="0"/>
        <xsl:with-param name="lastseq" select="number(@Occurs)"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="copy">
    <xsl:param name="data"/>
    <xsl:param name="seq"/>
    <xsl:param name="lastseq"/>
    <xsl:copy-of select="$data"></xsl:copy-of>
    <xsl:if test="$seq &lt; $lastseq">
        <xsl:call-template name="copy">
            <xsl:with-param name="data" select="$data"/>
            <xsl:with-param name="seq" select="$seq + 1"/>
            <xsl:with-param name="lastseq" select="$lastseq"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>
    
    <xsl:template match="*[@length]">
        <xsl:variable name="spacelenght" select="@length - string-length(.)"/>
        <xsl:value-of select="concat(substring($spaces, 1, $spacelenght), .)"/>
    </xsl:template>
    
</xsl:stylesheet>

输出

"      AAAA           BBBB                CCCC    DDDD                CCCC    DDDD                CCCC    DDDD                CCCC    DDDD                CCCC    DDDD                CCCC    DDDD                CCCC    DDDD                CCCC    DDDD                CCCC    DDDD                CCCC    DDDD"

请参阅 https://xsltfiddle.liberty-development.net/6q1S8AC/2 的转换

【讨论】:

  • 是的,成功了,非常感谢。
  • 嗨@Rupesh_Kr,我还有一个我认为可能很容易解决的要求,但我做不到。我已经编辑了上面的原始问题,它显示了如果它在哪里发生,那么它需要在该节点集周围循环 x 次,然后再继续。你有办法解决这个问题吗?
  • @user3063486 查看更新的答案
  • &lt;xsl:for-each select="1 to @Occurs"&gt; 需要 XSLT 2.0。
  • @michael.hor257k,抱歉,这是因为我在同一个编辑器中与我的个人工作同时工作(忘记更换处理器)。 :) 回答更新xsltfiddle.liberty-development.net/6q1S8AC/2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 2016-09-28
  • 1970-01-01
  • 2014-12-15
  • 2021-12-27
  • 1970-01-01
相关资源
最近更新 更多