【问题标题】:append data ton an element, based on matching this exact element基于匹配此确切元素,将数据附加到元素
【发布时间】:2017-10-05 14:24:52
【问题描述】:

给定以下 XML 作为输入,

<?xml version="1.0" encoding="UTF-8"?>
<TABLE NAME="TABLE.DB">
    <DATA RECORDS="2">
        <RECORD ID="4">
            <RECNO>0</RECNO>
            <SEQ>0</SEQ>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10354</NUMBER>
            <CN>PL</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>0</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
            <TOTALS>1</TOTALS>
        </RECORD>
        <RECORD ID="3">
            <RECNO>1</RECNO>
            <SEQ>0</SEQ>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10355</NUMBER>
            <CN>PL</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>0</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
            <TOTALS>1</TOTALS>
        </RECORD>
        <RECORD ID="2">
            <RECNO>2</RECNO>
            <SEQUENCE>0</SEQUENCE>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10356</NUMBER>
            <CN>PL 300 L</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>10</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
            <SUB_A>Some random data not matched.</SUB_A>
        </RECORD>
        <RECORD ID="1">
            <RECNO>3</RECNO>
            <SEQUENCE>0</SEQUENCE>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10357</NUMBER>
            <CN>PL 300 L</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>10</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
            <TOTALS>19837</TOTALS>
        </RECORD>
        <RECORD ID="0">
            <RECNO>3</RECNO>
            <SEQUENCE>0</SEQUENCE>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10358</NUMBER>
            <CN>PL 300 L</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>10</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
        </RECORD>
    </DATA>
</TABLE>

以及以下制表符分隔文件:

[yet another value.]\t10358
value i'd like to add\t10355
(another) value i'd like to add\t10357

我使用 \t 来显示文件中选项卡的位置。我想将在第一列中找到的数据附加到我尝试匹配的元素中,在本例中为 NUMBER。

因此,如果 NUMBER 等于第二列,则将在第一列中找到的值附加到它,使用 |作为分隔符。

如何得到以下结果,但要保持记录的顺序,对元素输出进行排序:

     <?xml version="1.0" encoding="UTF-8"?>
<TABLE NAME="TABLE.DB">
    <DATA RECORDS="2">
          <RECORD ID="0">
            <RECNO>3</RECNO>
            <SEQUENCE>0</SEQUENCE>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10358 | [yet another value.]</NUMBER>
            <CN>PL 300 L</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>10</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
        </RECORD>
        <RECORD ID="1">
            <RECNO>3</RECNO>
            <SEQUENCE>0</SEQUENCE>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10357 | (another) value i'd like to add</NUMBER>
            <CN>PL 300 L</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>10</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
            <TOTALS>19837</TOTALS>
        </RECORD>
        <RECORD ID="2">
            <RECNO>2</RECNO>
            <SEQUENCE>0</SEQUENCE>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10356</NUMBER>
            <CN>PL 300 L</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>10</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
            <SUB_A>Some random data not matched.</SUB_A>
        </RECORD>
        <RECORD ID="3">
            <RECNO>1</RECNO>
            <SEQ>0</SEQ>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10355 | value i'd like to add</NUMBER>
            <CN>PL</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>0</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
            <TOTALS>1</TOTALS>
        </RECORD>
         <RECORD ID="4">
            <RECNO>0</RECNO>
            <SEQ>0</SEQ>
            <DATE>17/12/1999 2:44:08 μμ</DATE>
            <ID>12/11/2015 3:15:25 μμ</ID>
            <NUMBER>10354</NUMBER>
            <CN>PL</CN>
            <PROPERTY>0</PROPERTY>
            <DAYS>0</DAYS>
            <CURRENTSTATUS>0</CURRENTSTATUS>
            <TOTALS>1</TOTALS>
        </RECORD>
    </DATA>
</TABLE>

我使用 Saxon 最新版本,v 9.8

【问题讨论】:

  • 您发布的输出是您想要的吗?不清楚排序标准是什么,输入和发布的输出似乎具有相同的顺序。
  • 输出是我想要的,在我的真实数据中,如果我按 NUMBER 排序,则输出记录混乱,我想按 RECORD ID 编号排序,输出结果.因此,在 xsl 中,我对 RECORD ID、NUMBER 和结果进行排序,我需要按 RECORD ID 编号对其进行排序
  • 而不是直接从 xsl:merge 输出结果存储在一个变量中,然后对变量的内容进行排序,参见w3.org/TR/xslt-30/#sorting,即在变量上使用xsl:perform-sort/xsl:sort 或使用@987654326 @.
  • 谢谢你,我会很感激一个带有上述输入输出的 xsl 示例,因为我也对合并操作感兴趣,如何做到这一点

标签: xslt-3.0


【解决方案1】:

xsl:merge 与您之前的问题类似,要对合并结果进行排序,您只需将xsl:merge 包装成xsl:perform-sort

<?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"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" exclude-result-prefixes="xs math"
    expand-text="yes" version="3.0">

    <xsl:param name="text-uri" as="xs:string">test2017100602.txt</xsl:param>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="lines" as="element(line)*">
        <xsl:apply-templates select="unparsed-text-lines($text-uri)"/>
    </xsl:variable>

    <xsl:template match=".[. instance of xs:string]">
        <xsl:variable name="tokens" as="xs:string*" select="tokenize(., '&#9;')[normalize-space()]"/>
        <line number="{$tokens[2]}">{$tokens[1]}</line>
    </xsl:template>

    <xsl:template match="TABLE/DATA">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:perform-sort>
                <xsl:sort select="xs:integer(@ID)"/>
                <xsl:merge>
                    <xsl:merge-source name="record" select="RECORD">
                        <xsl:merge-key select="NUMBER"/>
                    </xsl:merge-source>
                    <xsl:merge-source name="line" select="$lines" sort-before-merge="yes">
                        <xsl:merge-key select="@number"/>
                    </xsl:merge-source>
                    <xsl:merge-action>
                        <xsl:if test="current-merge-group('record')">
                            <xsl:copy>
                                <xsl:apply-templates select="@*, NUMBER/preceding-sibling::*"/>
                                <NUMBER>
                                    <xsl:value-of select="NUMBER, current-merge-group()[2]"
                                        separator=" | "/>
                                </NUMBER>
                                <xsl:apply-templates select="NUMBER/following-sibling::*"/>
                            </xsl:copy>
                        </xsl:if>
                    </xsl:merge-action>
                </xsl:merge>
            </xsl:perform-sort>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 2013-03-26
    • 2021-10-26
    • 2021-12-26
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多