【问题标题】:Trying to find the following two rows in XBRL instance document试图在 XBRL 实例文档中找到以下两行
【发布时间】:2015-02-15 11:30:49
【问题描述】:

我正在尝试为我遇到的以下问题找到一个 xslt 解决方案。

我想找到一组共享节点名称和属性但具有不同值的 3 个后续行。输入中的第一行包含一个标识符,第二行和第三行包含来自源系统的值。我想找到第二行和第三行具有不同值的集合。

例如

<eba7:mi235 contextRef="I-2014-E-dim-x43-x9-x156-x51-x14">78923</eba7:mi235>
<eba7:mi235 contextRef="I-2014-E-dim-x43-x9-x156-x51-x14">1111</eba7:mi235>
<eba7:mi235 contextRef="I-2014-E-dim-x43-x9-x156-x51-x14">2222</eba7:mi235>

也可能有一组行只有一个标识符,一组行有一个标识符,只有一个行有来自源系统的值,或者有一组行,其中第二行和第三行具有相同的值。

例如

<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x24-x195-x10-x4">78748</eba7:mi310>
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x24-x195-x10-x4">0</eba7:mi310>
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x25-x195-x10-x4">78804</eba7:mi310>
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x25-x195-x10-x4">12345</eba7:mi310>
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x25-x195-x10-x4">12345</eba7:mi310>

这些我不想在输出中找到。

我要创建的输出是

<eba7:mi235 id="78923" value1="1111" value2="2222" />

输入的结构使得行总是这样排列。所以我尝试使用位置来访问它们,但这没有用。

谁能指出我正确的方向?使用位置是否正确?

我已附加了一个文件,其中包含以下输入数据

谢谢。

保罗。

<?xml version="1.0" encoding="utf-8"?>
<xbrl xml:lang="en" xmlns="http://www.xbrl.org/2003/instance" xmlns:eba7="http://www.eba.europa.eu/xbrl/crr/dict/met" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:link="http://www.xbrl.org/2003/linkbase">
<link:schemaRef xlink:type="simple" xlink:href="http://www.eba.europa.eu/eu/fr/xbrl/crr/fws/corep/its-2013-02/2014-07-31/mod/corep_con.xsd" />
<context id="I-2014-E">
<entity>
  <identifier scheme="http://www.dnb.nl/id">578</identifier>
</entity>
<period>
  <instant>2014-12-31</instant>
</period>
</context>  
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x24-x195-x10-x4">78748</eba7:mi310>
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x24-x195-x10-x4">0</eba7:mi310>
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x25-x195-x10-x4">78804</eba7:mi310>
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x25-x195-x10-x4">12345</eba7:mi310>
<eba7:mi310 contextRef="I-2014-E-dim-x42-x9-x25-x195-x10-x4">12345</eba7:mi310>
<eba7:mi235 contextRef="I-2014-E-dim-x43-x9-x156-x51-x14">78923</eba7:mi235>
<eba7:mi235 contextRef="I-2014-E-dim-x43-x9-x156-x51-x14">1111</eba7:mi235>
<eba7:mi235 contextRef="I-2014-E-dim-x43-x9-x156-x51-x14">2222</eba7:mi235>
</xbrl>

【问题讨论】:

  • 这是一个分组问题。请指出您使用的是哪个版本的 XSLT - 每个版本的答案都大不相同。 -- 如果有4个序列怎么办?
  • 正在使用 XSLT 1.0 可能有 4 个序列:特定标识符的 3 个值。为了使示例尽可能简单,我将其省略了。我希望我可以针对这种情况扩展 Lingamurthy CS 的解决方案。
  • 正如我在回答中所说,这个问题的定义不是很好。更糟糕的是,您的输入示例格式不正确,无法用于测试。
  • 我已经更新了示例文件。它的格式不正确:第二个没有正确复制。
  • 出于兴趣,这是什么原因? EBA 申报规则禁止重复事实,因此不接受此类实例。

标签: xslt xbrl


【解决方案1】:

我认为这个问题的定义不够好;它可以有多种解释。

如果我们假设您想要:

  1. 根据标签名称和@contextRef 值相同both 对所有给定元素进行分组;元素的相互位置与此目的无关;

  2. 计算每组中的不同值;如果有三个或更多,则将具有公共标记名称的元素写入输出,并为该组中的每个不同值添加编号属性;

那么最好是这样做:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xbrli="http://www.xbrl.org/2003/instance" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="k1" match="*" use="concat(name(), '|', @contextRef)"/>
<xsl:key name="k2" match="*" use="concat(name(), '|', @contextRef, '|', .)"/>

<xsl:template match="/xbrli:xbrl">
    <xsl:copy>
        <xsl:for-each select="*[count(.|key('k1', concat(name(), '|', @contextRef))[1])=1]">
            <xsl:variable name="distinct-values" select="key('k1', concat(name(), '|', @contextRef)) [count(.|key('k2', concat(name(), '|', @contextRef, '|', .))[1])=1]"/>
            <xsl:if test="count($distinct-values) &gt;= 3">
                <xsl:copy>
                    <xsl:for-each select="$distinct-values">
                        <xsl:attribute name="value{position()}">
                            <xsl:value-of select="."/>
                        </xsl:attribute>
                    </xsl:for-each>
                </xsl:copy>
            </xsl:if>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用于以下格式良好的测试输入

<xbrl xmlns="http://www.xbrl.org/2003/instance" xmlns:eba7="http://www.eba.europa.eu/xbrl/crr/dict/met">
    <eba7:a contextRef="x">11</eba7:a>
    <eba7:a contextRef="x">12</eba7:a>

    <eba7:a contextRef="y">21</eba7:a>
    <eba7:a contextRef="y">22</eba7:a>
    <eba7:a contextRef="y">23</eba7:a>

    <eba7:b contextRef="x">31</eba7:b>
    <eba7:b contextRef="x">32</eba7:b>
    <eba7:b contextRef="x">33</eba7:b>
    <eba7:b contextRef="x">33</eba7:b>

    <eba7:c contextRef="x">41</eba7:c>
    <eba7:c contextRef="x">41</eba7:c>
    <eba7:c contextRef="x">42</eba7:c>
    <eba7:c contextRef="x">42</eba7:c>
</xbrl>

结果将是:

<?xml version="1.0" encoding="utf-8"?>
<xbrl xmlns="http://www.xbrl.org/2003/instance" xmlns:eba7="http://www.eba.europa.eu/xbrl/crr/dict/met">
   <eba7:a value1="21" value2="22" value3="23"/>
   <eba7:b value1="31" value2="32" value3="33"/>
</xbrl>

注意

  1. 你必须熟悉Muenchian分组方法才能理解这一点;

  2. 编号属性不是良好的 XML 做法。我建议您(或相关权力)重新考虑这一要求。

【讨论】:

    【解决方案2】:

    这个样式表能解决你的问题吗:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xbrli="http://www.xbrl.org/2003/instance" version="1.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    <xsl:strip-space elements="*"/>
    
    <xsl:key name="elements" match="*" use="@contextRef"/>
    
    <xsl:template match="/xbrli:xbrl">
        <xsl:copy>
            <xsl:apply-templates select="*[@contextRef
                                            and count(key('elements', @contextRef)) = 3 
                                            and key('elements', @contextRef)[2] != key('elements', @contextRef)[3]
                                            and count(. | key('elements', @contextRef)[1]) = 1]"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="*">
        <xsl:copy>
            <xsl:attribute name="id">
                <xsl:value-of select="."/>
            </xsl:attribute>
            <xsl:attribute name="value1">
                <xsl:value-of select="key('elements', @contextRef)[2]"/>
            </xsl:attribute>
            <xsl:attribute name="value2">
                <xsl:value-of select="key('elements', @contextRef)[3]"/>
            </xsl:attribute>
        </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>
    

    这里,key 被声明为匹配以@contextRef 为标识符的元素。第一个模板将模板应用于具有唯一 @contextRef 的第一个元素(以及那些与其他条件匹配的元素,例如 @contextRef 必须为 3 的总元素,并且第二个和第三个元素不能具有相同的值)。

    下一个模板匹配这些元素(来自第一个模板),并创建进一步的输出。

    【讨论】:

    • 你好 Lingamurthy,谢谢。这工作正常。我是否正确理解您的方法是:1)构建一个包含所有存在值的表,使用 contextRef 作为标识符。
    • @Paul,我相信 michael.hor257k 的回答是正确的。我的回答看不出元素名称是否相同。
    • '@Lingamurthy:你错过了不同的元素名称是对的。我认为扩展您的方法以包含元素名称会相对容易。我同意 Michaels 的解决方案更好,你的解决方案很容易理解。
    猜你喜欢
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多