为什么我的 xslt 选择了我没有指定的节点的子节点?
Why is my xslt selecting the child node of a node I haven't specified?
几年前我曾经使用过 xslt,虽然我不是专家,但我可以编写基本的转换。我现在遇到了我不明白的问题。
我在这里尝试从 foxml 记录中提取 Dublin Core 记录。 xml 中的都柏林核心记录和 foxml 基本上是一个 xml 标准,将大量 xml 记录分组。
这是我的 xml:
<?xml version="1.0" encoding="UTF-8"?>
<foxml:digitalObject VERSION="1.1" PID="vital:26113"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<foxml:objectProperties>
<foxml:property NAME="info:fedora/fedora-system:def/model#state" VALUE="Active"/>
<foxml:property NAME="info:fedora/fedora-system:def/model#label" VALUE="DCity/DCCPC_DC.xml"/>
<foxml:property NAME="info:fedora/fedora-system:def/model#ownerId" VALUE=""/>
<foxml:property NAME="info:fedora/fedora-system:def/model#createdDate"
VALUE="2016-09-06T19:49:51.257Z"/>
<foxml:property NAME="info:fedora/fedora-system:def/view#lastModifiedDate"
VALUE="2016-09-27T13:23:10.950Z"/>
<foxml:extproperty NAME="http://www.w3.org/1999/02/22-rdf-syntax-ns#type" VALUE="FedoraObject"/>
<foxml:extproperty NAME="info:fedora/fedora-system:def/model#contentModel" VALUE=""/>
</foxml:objectProperties>
<foxml:datastream ID="DC" STATE="A" CONTROL_GROUP="X" VERSIONABLE="true">
<foxml:datastreamVersion ID="DC.0" LABEL="Dublin Core for this Record"
CREATED="2016-09-06T19:49:51.290Z" MIMETYPE="text/xml"
FORMAT_URI="http://www.openarchives.org/OAI/2.0/oai_dc/" SIZE="653">
<foxml:xmlContent>
<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:title>St. Patricks</dc:title>
<dc:creator>Mary Mooney</dc:creator>
<dc:publisher>Publisher</dc:publisher>
<dc:format>Photograph</dc:format>
<dc:identifier>123456</dc:identifier>
<dc:identifier>100.jpg</dc:identifier>
<dc:coverage>1984</dc:coverage>
<dc:rights>Publisher</dc:rights>
</oai_dc:dc>
</foxml:xmlContent>
</foxml:datastreamVersion>
<foxml:datastreamVersion ID="DC.1" LABEL="Dublin Core for this Record"
CREATED="2016-09-27T13:23:10.894Z" MIMETYPE="text/xml"
FORMAT_URI="http://www.openarchives.org/OAI/2.0/oai_dc/" SIZE="653">
<foxml:xmlContent>
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:title>St Audoen's</dc:title>
<dc:creator>William Mooney</dc:creator>
<dc:publisher>Publisher</dc:publisher>
<dc:format>Photograph</dc:format>
<dc:identifier>10987654</dc:identifier>
<dc:identifier>200.jpg</dc:identifier>
<dc:coverage>1984</dc:coverage>
<dc:rights>Publisher</dc:rights>
</oai_dc:dc>
</foxml:xmlContent>
</foxml:datastreamVersion>
</foxml:datastream>
</foxml:digitalObject>
这是我的 xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
exclude-result-prefixes="xs"
version="2"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<xsl:output method="xml" indent="yes" name="xml"/>
<xsl:template match="/foxml:digitalObject/foxml:datastreamVersion[@ID eq DC.1]/foxml:xmlContent">
<metadata>
<xsl:value-of select="oai_dc:dc"/>
<xsl:copy-of select="."/>
</metadata>
</xsl:template>
</xsl:stylesheet>
我希望返回 ID=DC.1 的 foxml:datastreamVersion 的 DC 部分。相反,我得到以下信息:
<?xml version="1.0" encoding="UTF-8"?>
St. Patricks
Mary Mooney
Publisher
Photograph
123456
100.jpg
1984
Publisher
St Audoen's
William Mooney
Publisher
Photograph
10987654
200.jpg
1984
Publisher
所以我有两个明显的问题。
为什么从与我选择的属性不匹配的节点中选择 material?
为什么只返回文本,而不返回伴随的元素标签等?
我在 Saxon-EE.9.7.0.19 变压器上使用 oXygen 19.1。
首先,你的匹配表达式有问题,应该是这个...
/foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent
您在路径中错过了 foxml:datastream
。另外 "DC.1" 需要放在撇号中以使其成为字符串,而不是元素名称。
然而,在回答你的问题"why is it selecting material from the node that doesn't match the attribute"时,答案是"Because of XSLT's Built-In Templates"
当 XSLT 开始处理时,它将查找与文档节点 /
匹配的模板。您的 XSLT 中没有这样的模板,因此默认模板启动。实际上,这等同于在您的 XSLT 中包含这两个模板
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
这些会跳过元素,但会在找到它的地方输出文本,这会导致输出所有其他文本。要阻止这种情况发生,请将此模板添加到您的 XSLT
<xsl:template match="node()">
<xsl:apply-templates />
</xsl:template>
(在 XSLT 3.0 中,改为 <xsl:mode on-no-match="shallow-skip" />
)
至于第二个问题,当模板匹配时,您执行 <xsl:value-of select="oai_dc:dc"/>
并输出所有后代文本节点。您应该改用 xsl:copy-of
。
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
exclude-result-prefixes="xs dc oai_dc audit premis foxml xsi"
version="2"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<xsl:output method="xml" indent="yes" name="xml"/>
<xsl:template match="node()">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="/foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent">
<metadata>
<xsl:copy-of select="oai_dc:dc"/>
</metadata>
</xsl:template>
</xsl:stylesheet>
或者,只需匹配文档节点,然后使用 select.
定位要复制的节点
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
exclude-result-prefixes="xs dc oai_dc audit premis foxml xsi"
version="2"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<xsl:output method="xml" indent="yes" name="xml"/>
<xsl:template match="/">
<xsl:apply-templates select="foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent" />
</xsl:template>
<xsl:template match="foxml:xmlContent">
<metadata>
<xsl:copy-of select="oai_dc:dc"/>
</metadata>
</xsl:template>
</xsl:stylesheet>
几年前我曾经使用过 xslt,虽然我不是专家,但我可以编写基本的转换。我现在遇到了我不明白的问题。
我在这里尝试从 foxml 记录中提取 Dublin Core 记录。 xml 中的都柏林核心记录和 foxml 基本上是一个 xml 标准,将大量 xml 记录分组。
这是我的 xml:
<?xml version="1.0" encoding="UTF-8"?>
<foxml:digitalObject VERSION="1.1" PID="vital:26113"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<foxml:objectProperties>
<foxml:property NAME="info:fedora/fedora-system:def/model#state" VALUE="Active"/>
<foxml:property NAME="info:fedora/fedora-system:def/model#label" VALUE="DCity/DCCPC_DC.xml"/>
<foxml:property NAME="info:fedora/fedora-system:def/model#ownerId" VALUE=""/>
<foxml:property NAME="info:fedora/fedora-system:def/model#createdDate"
VALUE="2016-09-06T19:49:51.257Z"/>
<foxml:property NAME="info:fedora/fedora-system:def/view#lastModifiedDate"
VALUE="2016-09-27T13:23:10.950Z"/>
<foxml:extproperty NAME="http://www.w3.org/1999/02/22-rdf-syntax-ns#type" VALUE="FedoraObject"/>
<foxml:extproperty NAME="info:fedora/fedora-system:def/model#contentModel" VALUE=""/>
</foxml:objectProperties>
<foxml:datastream ID="DC" STATE="A" CONTROL_GROUP="X" VERSIONABLE="true">
<foxml:datastreamVersion ID="DC.0" LABEL="Dublin Core for this Record"
CREATED="2016-09-06T19:49:51.290Z" MIMETYPE="text/xml"
FORMAT_URI="http://www.openarchives.org/OAI/2.0/oai_dc/" SIZE="653">
<foxml:xmlContent>
<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:title>St. Patricks</dc:title>
<dc:creator>Mary Mooney</dc:creator>
<dc:publisher>Publisher</dc:publisher>
<dc:format>Photograph</dc:format>
<dc:identifier>123456</dc:identifier>
<dc:identifier>100.jpg</dc:identifier>
<dc:coverage>1984</dc:coverage>
<dc:rights>Publisher</dc:rights>
</oai_dc:dc>
</foxml:xmlContent>
</foxml:datastreamVersion>
<foxml:datastreamVersion ID="DC.1" LABEL="Dublin Core for this Record"
CREATED="2016-09-27T13:23:10.894Z" MIMETYPE="text/xml"
FORMAT_URI="http://www.openarchives.org/OAI/2.0/oai_dc/" SIZE="653">
<foxml:xmlContent>
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:title>St Audoen's</dc:title>
<dc:creator>William Mooney</dc:creator>
<dc:publisher>Publisher</dc:publisher>
<dc:format>Photograph</dc:format>
<dc:identifier>10987654</dc:identifier>
<dc:identifier>200.jpg</dc:identifier>
<dc:coverage>1984</dc:coverage>
<dc:rights>Publisher</dc:rights>
</oai_dc:dc>
</foxml:xmlContent>
</foxml:datastreamVersion>
</foxml:datastream>
</foxml:digitalObject>
这是我的 xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
exclude-result-prefixes="xs"
version="2"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<xsl:output method="xml" indent="yes" name="xml"/>
<xsl:template match="/foxml:digitalObject/foxml:datastreamVersion[@ID eq DC.1]/foxml:xmlContent">
<metadata>
<xsl:value-of select="oai_dc:dc"/>
<xsl:copy-of select="."/>
</metadata>
</xsl:template>
</xsl:stylesheet>
我希望返回 ID=DC.1 的 foxml:datastreamVersion 的 DC 部分。相反,我得到以下信息:
<?xml version="1.0" encoding="UTF-8"?>
St. Patricks
Mary Mooney
Publisher
Photograph
123456
100.jpg
1984
Publisher
St Audoen's
William Mooney
Publisher
Photograph
10987654
200.jpg
1984
Publisher
所以我有两个明显的问题。
为什么从与我选择的属性不匹配的节点中选择 material?
为什么只返回文本,而不返回伴随的元素标签等?
我在 Saxon-EE.9.7.0.19 变压器上使用 oXygen 19.1。
首先,你的匹配表达式有问题,应该是这个...
/foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent
您在路径中错过了 foxml:datastream
。另外 "DC.1" 需要放在撇号中以使其成为字符串,而不是元素名称。
然而,在回答你的问题"why is it selecting material from the node that doesn't match the attribute"时,答案是"Because of XSLT's Built-In Templates"
当 XSLT 开始处理时,它将查找与文档节点 /
匹配的模板。您的 XSLT 中没有这样的模板,因此默认模板启动。实际上,这等同于在您的 XSLT 中包含这两个模板
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
这些会跳过元素,但会在找到它的地方输出文本,这会导致输出所有其他文本。要阻止这种情况发生,请将此模板添加到您的 XSLT
<xsl:template match="node()">
<xsl:apply-templates />
</xsl:template>
(在 XSLT 3.0 中,改为 <xsl:mode on-no-match="shallow-skip" />
)
至于第二个问题,当模板匹配时,您执行 <xsl:value-of select="oai_dc:dc"/>
并输出所有后代文本节点。您应该改用 xsl:copy-of
。
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
exclude-result-prefixes="xs dc oai_dc audit premis foxml xsi"
version="2"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<xsl:output method="xml" indent="yes" name="xml"/>
<xsl:template match="node()">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="/foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent">
<metadata>
<xsl:copy-of select="oai_dc:dc"/>
</metadata>
</xsl:template>
</xsl:stylesheet>
或者,只需匹配文档节点,然后使用 select.
定位要复制的节点<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:audit="info:fedora/fedora-system:def/audit#" xmlns:premis="http://www.loc.gov/standards/premis/v1"
exclude-result-prefixes="xs dc oai_dc audit premis foxml xsi"
version="2"
xmlns:foxml="info:fedora/fedora-system:def/foxml#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="info:fedora/fedora-system:def/foxml# http://www.fedora.info/definitions/1/0/foxml1-1.xsd">
<xsl:output method="xml" indent="yes" name="xml"/>
<xsl:template match="/">
<xsl:apply-templates select="foxml:digitalObject/foxml:datastream/foxml:datastreamVersion[@ID eq 'DC.1']/foxml:xmlContent" />
</xsl:template>
<xsl:template match="foxml:xmlContent">
<metadata>
<xsl:copy-of select="oai_dc:dc"/>
</metadata>
</xsl:template>
</xsl:stylesheet>