【问题标题】:reshape xml using xslt-3, splitting a record to many records if it has a certain element使用 xslt-3 重塑 xml,如果它具有某个元素,则将一条记录拆分为多条记录
【发布时间】:2018-12-17 16:42:58
【问题描述】:

给定以下 xml 文件,我只需要选择那些具有 <marc:datafield tag="911",并且在每个 911 中,仅提取具有代码 h 或 j 的元素:<marc:subfield code="h"><marc:subfield code="j">。两者都可以有文本值,即数字和文本。那么选中的记录和元素应该会改变,所以我们保持001的值为RECNO,并且我们添加一个唯一的RECORD ID增量值,从1开始。如果不存在h或j,则记录没有对应的元素. Name_1 是, and Name_2 is the new element name for的新元素名称`

<?xml version="1.0" encoding="UTF-8" ?>
<marc:collection
    xmlns:marc="http://www.loc.gov/MARC21/slim"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
    <marc:record>
        <marc:controlfield tag="001">7</marc:controlfield>
        </marc:datafield>
        <marc:datafield tag="911" ind1=" " ind2=" ">
            <marc:subfield code="o">KEN</marc:subfield>
            <marc:subfield code="b">MAIN</marc:subfield>
            <marc:subfield code="e">20171027</marc:subfield>
            <marc:subfield code="n">V.6</marc:subfield>
            <marc:subfield code="d">001000000918</marc:subfield>
            <marc:subfield code="a">001000000918</marc:subfield>
            <marc:subfield code="h">v.1</marc:subfield>
            <marc:subfield code="j">1686</marc:subfield>
        </marc:datafield>
        <marc:datafield tag="911" ind1=" " ind2=" ">
            <marc:subfield code="o">KEN</marc:subfield>
            <marc:subfield code="b">MAIN</marc:subfield>
            <marc:subfield code="e">20171027</marc:subfield>
            <marc:subfield code="n">V.6</marc:subfield>
            <marc:subfield code="d">001000000921</marc:subfield>
            <marc:subfield code="a">001000000921</marc:subfield>
            <marc:subfield code="h">v.2</marc:subfield>
            <marc:subfield code="j">1687</marc:subfield>
        </marc:datafield>
        <marc:datafield tag="911" ind1=" " ind2=" ">
            <marc:subfield code="o">KEN</marc:subfield>
            <marc:subfield code="b">MAIN</marc:subfield>
            <marc:subfield code="e">20171027</marc:subfield>
            <marc:subfield code="n">V.6</marc:subfield>
            <marc:subfield code="d">001000000920</marc:subfield>
            <marc:subfield code="a">001000000920</marc:subfield>
            <marc:subfield code="h">v.2</marc:subfield>
            <marc:subfield code="j">1687</marc:subfield>
        </marc:datafield>
        <marc:datafield tag="911" ind1=" " ind2=" ">
            <marc:subfield code="o">KEN</marc:subfield>
            <marc:subfield code="b">MAIN</marc:subfield>
            <marc:subfield code="e">20171027</marc:subfield>
            <marc:subfield code="n">V.6</marc:subfield>
            <marc:subfield code="d">001000000919</marc:subfield>
            <marc:subfield code="a">001000000919</marc:subfield>
            <marc:subfield code="h">v.1</marc:subfield>
            <marc:subfield code="j">1686</marc:subfield>
        </marc:datafield>
    </marc:record>
    <marc:record>
    <marc:controlfield tag="001">12481</marc:controlfield>
    <marc:datafield tag="911" ind1=" " ind2=" ">
        <marc:subfield code="o">KEN</marc:subfield>
        <marc:subfield code="b">MAIN</marc:subfield>
        <marc:subfield code="e">20160324</marc:subfield>
        <marc:subfield code="n">II.5</marc:subfield>
        <marc:subfield code="d">061000019180</marc:subfield>
        <marc:subfield code="a">061000019180</marc:subfield>
        <marc:subfield code="h">v.5</marc:subfield>
    </marc:datafield>
    <marc:datafield tag="911" ind1=" " ind2=" ">
        <marc:subfield code="o">KEN</marc:subfield>
        <marc:subfield code="b">MAIN</marc:subfield>
        <marc:subfield code="e">20160324</marc:subfield>
        <marc:subfield code="n">II.5</marc:subfield>
        <marc:subfield code="d">061000019181</marc:subfield>
        <marc:subfield code="a">061000019181</marc:subfield>
        <marc:subfield code="h">v.4</marc:subfield>
    </marc:datafield>
</marc:record>
<marc:record>
    <marc:controlfield tag="001">1</marc:controlfield>
</marc:record>
</marc:collection>

预期输出:

<?xml version="1.0" encoding="UTF-8" ?>
<marc:collection
    xmlns:marc="http://www.loc.gov/MARC21/slim"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
    <RECORD ID="1">   
        <RECNO>7</RECNO>
        <NAME_1>v.1</NAME_1>
        <NAME_2>1686</NAME_2>
        </RECORD>
        <RECORD ID="2">
            <RECNO>7</RECNO>
            <NAME_1>v.2</NAME_1>
            <NAME_2>1687</NAME_2>
        </RECORD>
        <RECORD ID="3">
            <RECNO>7</RECNO>
            <NAME_1>v.2</NAME_1>
            <NAME_2>1687</NAME_2>
        </RECORD>
        <RECORD ID="4">
            <RECNO>7</RECNO>
            <NAME_1>v.4</NAME_1>
            <NAME_2>16887</NAME_2>
        </RECORD>
        <RECORD ID="5">
            <RECNO>12481</RECNO>
            <NAME_1>v.5</NAME_1>
        </RECORD>
    <RECORD ID="6">
            <RECNO>12481</RECNO>
            <NAME_1>v.4</NAME_1>
        </RECORD>
</marc:collection>

如何使用 xslt-3 实现上述结果? (撒克逊 9.8 HE)

【问题讨论】:

  • 你的问题是有道理的。它是或。如果 h 或 j 不存在,则生成的记录没有对应的元素。
  • 因此您知道要选择/处理和转换哪些元素。您能向我们展示任何 XSLT 样式表的尝试吗?此外,NAME_1/NAME_2 结果元素的值是从哪里获取的?例如,&lt;NAME_2&gt;a1687&lt;/NAME_2&gt; 来自哪里?
  • NAME_1 代表代码 h,NAME_2 代表代码 j。我尝试使用 xsl:template match 和 xsl:copy-of select 解决这个问题

标签: xslt-3.0


【解决方案1】:

我没有看到任何真正的分裂,您似乎只是想将 record/datafield[subfield/@code = ('h', 'j')] 元素映射到 RECORD 元素,然后将 subfield 元素映射到 NAME_1/NAME_2 元素:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="http://www.loc.gov/MARC21/slim"
    expand-text="yes"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:output indent="yes"/>

  <xsl:template match="/*">
      <xsl:copy>
          <xsl:copy-of select="@*"/>
          <xsl:apply-templates select="record/datafield[subfield/@code = ('h', 'j')]"/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="datafield">
      <RECORD ID="{position()}">
          <RECNO>{ancestor::record/controlfield}</RECNO>
          <xsl:apply-templates select="subfield[@code = ('h', 'j')]"/>
      </RECORD>
  </xsl:template>

  <xsl:template match="subfield[@code = 'h']">
      <NAME_1>{.}</NAME_1>
  </xsl:template>

  <xsl:template match="subfield[@code = 'j']">
      <NAME_2>{.}</NAME_2>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bdxtrh

【讨论】:

  • 拆分意思是输出中1条初始记录变成了4条记录,非常感谢
猜你喜欢
  • 1970-01-01
  • 2022-10-14
  • 2022-12-09
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 2019-02-18
相关资源
最近更新 更多