我有一个xml文件,其中名为identifier的元素可以出现1次以上。存储在这些标识符元素中的值可以是文件名,其他本地标识符,所谓的PID(数字:数字格式)和句柄(http://hdl.handle.net/ .... url)。此信息可以按任何顺序出现,或PID可以是1st或句柄或文件名;它是随机的。我对PID和句柄感兴趣,数据有这三种场景用于PID并在父元素记录中处理:
1)PID仅在标识符元素组中出现一次 2)句柄仅在标识符元素组中出现一次 3)PID和句柄一次出现在标识符元素集中。
在方案1中,我想添加前缀" http://hdl.handle.net/11134/"到PID并将此值放在标识符元素中,然后添加一个元素源,我根据PID构建一个url。
在方案2中,我想将标识符字段的值添加到新xml文件中的相同标识符,并在新的源元素中基于此句柄构建URL。
在方案3中,我想要选择PID或句柄,而不是两者。让我们说我只想要句柄而不是PID,然后我做方案2.
如果同时存在PID和句柄,我有2个标识符和2个源元素,我不知道如何更改它,以便只有场景2才会这样做。
我是xslt的新手,不知道我做错了什么。我尝试了previous-sibling和for-each的变体并选择,但是场景3的结果总是2个标识符元素和2个源元素。
感谢您的帮助。
这是xml的一个示例:
<record>
<identifier>200003:93939393</identifier>
<identifier>sampleFilename.jpg</identifier>
<identifier>otherLocalidentifier</identifier>
<identifier>hdl.handle.net/11134/200003:93939393</identifier>
</record>
<record>
<identifier>otherfilename.tiff</identifier>
<identifier>hdl.handle.net/11134/50003:93939393</identifier>
</record>
<record>
<identifier>somelocal name</identifier>
<identifier>94949:93999393</identifier>
</record>
在这个xml中,标识符还有其他值,标识符元素的数量是随机的,PID和句柄可以按任何顺序出现。
我想要的输出是在新的xml文件中始终只有1个标识符和1个源元素:
<record>
<identifier>hdl.handle.net/11134/200003:93939393</identifier>
<source>200003:93939393/TN</source>
</record>
<record>
<identifier>hdl.handle.net/11134/50003:93939393</identifier>
<source>50003:93939393/TN</source>
</record>
<record>
<identifier>http://hdl.handle.net/11134/94949:93999393</identifier>
<source>94949:93999393/TN</source>
</record>
<xsl:template match="identifier">
<xsl:variable name="idvalue">
<xsl:choose>
<xsl:when test="contains(., 'http://hdl.handle.net/')">
<xsl:value-of select="normalize-space(.)"/>
</xsl:when>
<xsl:when test="matches(., '^\d{5,10}[:]\d*$')">
<xsl:text>http://hdl.handle.net/11134/</xsl:text>
<xsl:value-of select="normalize-space(.)"/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="$idvalue[1]"></xsl:value-of>
答案 0 :(得分:0)
<强>予。这是正确的XSLT 2.0转换:
std::function
应用于以下XML文档:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vPat"
select="'(^\d{5,10}:\d+$)|(^hdl.handle.net/11134/\d{5,10}:\d+$)'"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record/*[matches(., $vPat)][1]">
<identifier>
<xsl:value-of select="replace(.,'^(.*?)(\d{5,10}:\d+)$','hdl.handle.net/11134/$2')"/>
</identifier>
<source>
<xsl:value-of select="replace(.,'^(.*?)(\d{5,10}:\d+)$', '$2/TN')"/>
</source>
</xsl:template>
<xsl:template match="record/*" priority="0"/>
</xsl:stylesheet>
生成想要的正确结果:
<t>
<record>
<identifier>other/Local/12345:67/identifier</identifier>
<identifier>200003:93939393</identifier>
<identifier>sampleFilename.jpg</identifier>
<identifier>hdl.handle.net/11134/200003:93939393</identifier>
</record>
<record>
<identifier>Some/50003:</identifier>
<identifier>otherfilename.tiff</identifier>
<identifier>hdl.handle.net/11134/50003:93939393</identifier>
</record>
<record>
<identifier>somelocal name</identifier>
<identifier>94949:93999393</identifier>
</record>
</t>
<强> II。这个XSLT 1.0转换:
<t>
<record>
<identifier>hdl.handle.net/11134/200003:93939393</identifier>
<source>200003:93939393/TN</source>
</record>
<record>
<identifier>hdl.handle.net/11134/50003:93939393</identifier>
<source>50003:93939393/TN</source>
</record>
<record>
<identifier>hdl.handle.net/11134/94949:93999393</identifier>
<source>94949:93999393/TN</source>
</record>
</t>
应用于同一XML文档时,再次生成所需的正确结果:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template priority="3" match=
"record/*[floor(substring-before(., ':')) = substring-before(., ':')
and floor(substring-after(., ':')) = substring-after(., ':')
]">
<identifier><xsl:value-of select="concat('hdl.handle.net/11134/',.)"/></identifier>
<source><xsl:value-of select="concat(., '/TN')"/></source>
</xsl:template>
<xsl:template match=
"record[not(*[floor(substring-before(., ':')) = substring-before(., ':')
and floor(substring-after(., ':')) = substring-after(., ':')
]
)]
/*[starts-with(., 'hdl.handle.net/11134/')]">
<xsl:copy-of select="."/>
<source><xsl:value-of select="
concat(substring-after(., 'hdl.handle.net/11134/'), '/TN')"/></source>
</xsl:template>
<xsl:template match="text() |identifier"/>
</xsl:stylesheet>
答案 1 :(得分:0)
假设你的正则表达式唯一地标识了一个PID,我建议你这样试试:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record">
<xsl:variable name="pid" select="(identifier/tokenize(., '/')[matches(., '^\d{5,10}[:]\d*$')])[1]"/>
<xsl:copy>
<identifier><xsl:value-of select="concat('hdl.handle.net/11134/', $pid)"/></identifier>
<source><xsl:value-of select="concat($pid, '/TN')"/></source>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>