XSL value-of似乎无法从XML中获取值

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中获取标题值。我只能看到:

Description

Hello

但如果我从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是由表单生成的,如果我删除默认命名空间,它将无法正常工作。我甚至不知道如何解决这个问题或者是否做错了什么。请帮忙。

提前感谢。

2个回答

4
/mods:mods/*(一个斜杠)可以匹配文档元素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>

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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接