4

我有一个包含以下内容的 xml 文件:

<?xml version="1.0"?>
<mods xmlns="http://www.loc.gov/mods/v3" xmlns:mods="http://www.loc.gov/mods/v3"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xlink="http://www.w3.org/1999/xlink">
   <titleInfo><title>A-Title-01</title></titleInfo>
</mods>

还有一个 XSL 文件:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <h2>Description</h2>
    <p>Hello</p>
    <p><xsl:value-of select="titleInfo/title"/></p>
</xsl:template>
</xsl:stylesheet>

我的问题是我没有得到 xHTML 中的标题值。我只能看到

描述

你好

但是如果我像这样从 xml 中删除默认命名空间:

<?xml version="1.0"?>
<mods xmlns:mods="http://www.loc.gov/mods/v3"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xlink="http://www.w3.org/1999/xlink">
   <titleInfo><title>A-Title-01</title></titleInfo>
</mods>

并将样式表的匹配更改为<xsl:template match="/mods">我可以看到标题值。

但我无法从 xml 中删除默认命名空间,因为 xml 是由表单生成的,如果我删除默认命名空间,它将不起作用。我什至不知道如何解决这个问题,或者我做错了什么。请帮忙。

提前致谢。

4

2 回答 2

4

模板匹配/不是从文档元素开始的,它是“根节点”——在任何内容之前。文档中的第一个 node() 不必是文档元素,它可以是注释或处理指令,并且可以是“根节点”的子节点。

因此,如果您想匹配文档元素mods,并且您不想担心模板匹配的命名空间可能是/*. 然后您的 XPath 选择相对于文档元素的元素将起作用。

但是,您的titleInfotitle元素继承了文档元素的命名空间。所以,如果你想匹配它们,你有几个选择:

  1. 声明命名空间并给它一个前缀,以便您可以在 XPath 中使用它
  2. 使用谓词过滤器在元素上进行一般匹配,以匹配 local-name() 和 namespace-uri() - 但如果您知道 URI,则更容易声明它并使用选项 #1 中的前缀。
  3. 使用谓词过滤器在元素上进行一般匹配,以仅匹配 local-name()。不干净/正确,但可能会起作用。
  4. 对每个步骤的元素进行一般匹配,并依靠这个简单文档的结构来找到您正在寻找的元素

选项1:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:m="http://www.loc.gov/mods/v3">
        <xsl:template match="/m:mods">
            <h2>Description</h2>
            <p>Hello</p>
            <p><xsl:value-of select="m:titleInfo/m:title"/></p>
        </xsl:template>
</xsl:stylesheet>

选项#2:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/*[local-name()='mods' and namespace-uri()='http://www.loc.gov/mods/v3']">
            <h2>Description</h2>
            <p>Hello</p>
        <p><xsl:value-of select="*[local-name()='titleInfo' 
                                   and namespace-uri()='http://www.loc.gov/mods/v3']/*[local-name()='title' and namespace-uri()='http://www.loc.gov/mods/v3']"/></p>
        </xsl:template>
</xsl:stylesheet>

选项#3:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/*[local-name()='mods']">
            <h2>Description</h2>
            <p>Hello</p>
        <p><xsl:value-of select="*[local-name()='titleInfo']/*[local-name()='title']"/></p>
        </xsl:template>
</xsl:stylesheet>

选项#4:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/*">
        <h2>Description</h2>
        <p>Hello</p>
        <p><xsl:value-of select="*/*"/></p>
    </xsl:template>
</xsl:stylesheet>
于 2013-09-19T01:22:02.700 回答
3

为您的命名空间添加前缀声明,然后匹配前缀名称。

以下未经测试:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:loc="http://www.loc.gov/mods/v3" exclude-result-prefixes="loc">
<xsl:template match="/loc:mods">
    <h2>Description</h2>
    <p>Hello</p>
    <p><xsl:value-of select="loc:titleInfo/loc:title"/></p>
</xsl:template>
</xsl:stylesheet>
于 2013-09-19T01:17:59.983 回答