XSL值似乎没有从xml获得值

时间:2013-09-19 00:57:25

标签: xml xslt xsd value-of

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

先谢谢。

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:3)

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

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

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

  1. 声明命名空间并为其指定一个前缀,以便在XPath中使用它
  2. 通常在元素上匹配谓词过滤器以匹配local-name()和namespace-uri() - 但如果您知道URI,则更容易声明它并在选项#1中使用前缀。
  3. 通常在元素上匹配谓词过滤器以匹配local-name()。不是干净/适当,但可能会有效。
  4. 在每个步骤的元素上进行一般匹配,并依靠此简单文档的结构来查找您要查找的元素
  5. 选项#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>