使用 xslt-3 重塑 xml,如果记录具有特定元素,则将其拆分为多条记录
reshape xml using xslt-3, splitting a record to many records if it has a certain element
给定以下 xml 文件,我只需要 select 那些具有
<marc:datafield tag="911"
,并且在每个 911
中,仅提取代码为 h 或 j 的元素:<marc:subfield code="h">
或 <marc:subfield code="j">
。两者都可以有文本值,即数字和文本。然后 selected 记录和元素应该被改变,所以我们将 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)
我没有看到任何真正的拆分,您似乎只是想将 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>
给定以下 xml 文件,我只需要 select 那些具有
<marc:datafield tag="911"
,并且在每个 911
中,仅提取代码为 h 或 j 的元素:<marc:subfield code="h">
或 <marc:subfield code="j">
。两者都可以有文本值,即数字和文本。然后 selected 记录和元素应该被改变,所以我们将 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)
我没有看到任何真正的拆分,您似乎只是想将 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>