gpt4 book ai didi

xslt - 当数据结构未知时排除某些子节点

转载 作者:行者123 更新时间:2023-12-03 15:32:07 25 4
gpt4 key购买 nike

编辑 -
我找到了问题的解决方案并发布了问答 here .

我希望处理符合美国国会图书馆 EAD 标准的 XML(找到 here)。不幸的是,该标准对于 XML 的结构非常松散。

例如 <bioghist>标签可以存在于 <archdesc> 中标签,或在 <descgrp> 内标签,或嵌套在另一个 <bioghist> 中标签,或以上的组合,或者可以完全省略。我发现只选择我正在寻找的 bioghist 标签而不选择其他标签是非常困难的。

下面是我的 XSLT 可能需要处理的几种不同的 EAD XML 文档:

第一个例子

<ead>
<eadheader>
<archdesc>
<bioghist>one</bioghist>
<dsc>
<c01>
<descgrp>
<bioghist>two</bioghist>
</descgrp>
<c02>
<descgrp>
<bioghist>
<bioghist>three</bioghist>
</bioghist>
</descgrp>
</c02>
</c01>
</dsc>
</archdesc>
</eadheader>
</ead>

第二个例子
<ead>
<eadheader>
<archdesc>
<descgrp>
<bioghist>
<bioghist>one</bioghist>
</bioghist>
</descgrp>
<dsc>
<c01>
<c02>
<descgrp>
<bioghist>three</bioghist>
</descgrp>
</c02>
<bioghist>two</bioghist>
</c01>
</dsc>
</archdesc>
</eadheader>
</ead>

第三个例子
<ead>
<eadheader>
<archdesc>
<descgrp>
<bioghist>one</bioghist>
</descgrp>
<dsc>
<c01>
<c02>
<bioghist>three</bioghist>
</c02>
</c01>
</dsc>
</archdesc>
</eadheader>
</ead>

如您所见,EAD XML 文件可能具有 <bioghist>几乎在任何地方标记。我想产生的实际输出太复杂了,无法在这里发布。上述三个 EAD 示例的输出的简化示例可能如下所示:

第一个示例的输出
<records>
<primary_record>
<biography_history>first</biography_history>
</primary_record>
<child_record>
<biography_history>second</biography_history>
</child_record>
<granchild_record>
<biography_history>third</biography_history>
</granchild_record>
</records>

第二个示例的输出
<records>
<primary_record>
<biography_history>first</biography_history>
</primary_record>
<child_record>
<biography_history>second</biography_history>
</child_record>
<granchild_record>
<biography_history>third</biography_history>
</granchild_record>
</records>

第三个示例的输出
<records>
<primary_record>
<biography_history>first</biography_history>
</primary_record>
<child_record>
<biography_history></biography_history>
</child_record>
<granchild_record>
<biography_history>third</biography_history>
</granchild_record>
</records>

如果我想提取“第一个”bioghist 值并将其放入 <primary_record> ,我不能简单地 <xsl:apply-templates select="/ead/eadheader/archdesc/bioghist" ,因为该标签可能不是 <archdesc> 的直接后代标签。它可能被 <descgrp> 包裹或 <bioghist>或其组合。我不能 select="//bioghist" ,因为这将拉动所有 <bioghist>标签。我什至不能 select="//bioghist[1]"因为实际上可能没有 <bioghist>在那里标记,然后我会将值拉到 <c01> 以下,这是“第二个”,应该稍后处理。

这已经是一个很长的帖子了,但另一个问题是可以有无限数量的 <cxx>节点,最多嵌套 12 层。我目前正在递归处理它们。我尝试将我当前正在处理的节点(例如 <c01>)保存为名为“RN”的变量,然后运行 ​​ <xsl:apply-templates select=".//bioghist [name(..)=name($RN) or name(../..)=name($RN)]"> .这适用于某些形式的 EAD,其中 <bioghist>标签没有嵌套太深,但是如果它必须处理由喜欢将标签包装在其他标签中的人创建的 EAD 文件(根据 EAD 标准完全没问题),它就会失败。

我喜欢的是以某种方式说的
  • 获取任何 <bioghist>标记当前节点下方的任何位置,但
  • 如果您遇到 <c??>,请不要深入挖掘标签

  • 我希望我已经把情况说清楚了。如果我有什么不明确的地方,请告诉我。您能提供的任何帮助将不胜感激。谢谢。

    最佳答案

    由于要求相当模糊,任何答案仅反射(reflect)其作者所做的猜测。

    这是我的:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:my="my:my" exclude-result-prefixes="my">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <my:names>
    <n>primary_record</n>
    <n>child_record</n>
    <n>grandchild_record</n>
    </my:names>

    <xsl:variable name="vNames" select="document('')/*/my:names/*"/>

    <xsl:template match="/">
    <xsl:apply-templates select=
    "//bioghist[following-sibling::node()[1]
    [self::descgrp]
    ]"/>
    </xsl:template>

    <xsl:template match="bioghist">
    <xsl:variable name="vPos" select="position()"/>

    <xsl:element name="{$vNames[position() = $vPos]}">
    <xsl:value-of select="."/>
    </xsl:element>
    </xsl:template>

    <xsl:template match="text()"/>
    </xsl:stylesheet>

    当此转换应用于提供的 XML 文档时:
    <ead>
    <eadheader>
    <archdesc>
    <bioghist>first</bioghist>
    <descgrp>
    <bioghist>first</bioghist>
    <bioghist>
    <bioghist>first</bioghist></bioghist>
    </descgrp>
    <dsc>
    <c01>
    <bioghist>second</bioghist>
    <descgrp>
    <bioghist>second</bioghist>
    <bioghist>
    <bioghist>second</bioghist></bioghist>
    </descgrp>
    <c02>
    <bioghist>third</bioghist>
    <descgrp>
    <bioghist>third</bioghist>
    <bioghist>
    <bioghist>third</bioghist></bioghist>
    </descgrp>
    </c02>
    </c01>
    </dsc>
    </archdesc>
    </eadheader>
    </ead>

    产生了想要的结果 :
    <primary_record>first</primary_record>
    <child_record>second</child_record>
    <grandchild_record>third</grandchild_record>

    关于xslt - 当数据结构未知时排除某些子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11233708/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com