我找到了问题的解决方案并发布了Q& A 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>或其组合.我不能选择=“// bioghist”,因为这将拉动所有< bioghist>标签.我甚至不能选择=“// bioghist [1]”,因为实际上可能没有< bioghist>标记然后我将拉出< c01>下面的值,这是“秒”,应该稍后处理.
这已经是一个很长的帖子,但另一个问题是可以有无限数量的< cxx>节点,最多嵌套12个级别.我正在递归处理它们.我已经尝试将我正在处理的节点(例如< c01>)保存为名为’RN’的变量,然后运行< xsl:apply-templates select =“.// bioghist [name(..) =名称($RN)或名称(../..)=名称($RN)]“>.这适用于某些形式的EAD,其中< bioghist>标签不是嵌套得太深,但如果它必须处理由喜欢在其他标签中包装标签的人创建的EAD文件,它将失败(根据EAD标准,这完全没问题).
我所喜欢的就是说
>获取任何< bioghist>标记当前节点下面的任何地方但是
>如果你打了一个< c ??>,就不要深入挖掘标签
我希望我的情况清楚.如果我留下任何含糊不清的地方,请告诉我.您将提供的任何帮助将不胜感激.谢谢.
解决方法
这是我的:
<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>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。