【问题标题】:XSLT 1.0: xsl:if test xpath not working for tags without a namespace?XSLT 1.0:xsl:if 测试 xpath 不适用于没有命名空间的标签?
【发布时间】:2014-03-12 11:29:54
【问题描述】:

考虑以下 XML:

<mergeddocx>

    <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">

        <w:hyperlink r:id="rId9">
            <w:r>
                <w:t>Hello World!!</w:t>
            </w:r>
        </w:hyperlink>

    </w:document>

    <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
        <Relationship Id="rId9" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="http://x1y1z1.com/" TargetMode="External" />
    </Relationships>

</mergeddocx>

当我尝试使用以下 XSL 脚本解析它时:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
exclude-result-prefixes="w r">

<xsl:template match="w:hyperlink">
    <a>
        <xsl:variable name="rId">
            <xsl:value-of select="@r:id"/>
        </xsl:variable>
        <xsl:if test="/mergeddocx/Relationships">
            <xsl:attribute name="href">
                <xsl:value-of select="$rId"/>
            </xsl:attribute>
        </xsl:if>
        <xsl:attribute name="target">
            <xsl:text>_blank</xsl:text>
        </xsl:attribute>
    </a>
</xsl:template>

而不是得到预期的输出:

<a href="rId9" target="_blank">
</a>

我得到的是:

<a target="_blank"/>

xsl:if 中的 xpath 不接受 mergeddocx 标记内有 Relationships 标记。但是,当我在测试 xpath 中仅使用 /mergeddocx 时,它可以正常工作。

我在这里做错了什么?如何在我的 xpath 中包含包含非命名空间的标签?

提前谢谢!!

【问题讨论】:

    标签: xml xslt xpath xslt-1.0 openxml


    【解决方案1】:

    试试这个方法:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
    xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
    xmlns:rel="http://schemas.openxmlformats.org/package/2006/relationships"
    exclude-result-prefixes="w r rel">
    
    <xsl:template match="w:hyperlink">
        <a>
            <xsl:variable name="rId">
                <xsl:value-of select="@r:id"/>
            </xsl:variable>
            <xsl:if test="/mergeddocx/rel:Relationships">
                <xsl:attribute name="href">
                    <xsl:value-of select="$rId"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:attribute name="target">
                <xsl:text>_blank</xsl:text>
            </xsl:attribute>
        </a>
    </xsl:template>
    
    </xsl:stylesheet>
    

    注意 xmlns:r 和 xmlns:rel 命名空间之间的区别。它们不一样。

    【讨论】:

    • 谢谢它的工作。但是为什么rel?是某种默认属性还是什么?
    • @SurenderThakran 这纯粹是我选择的任意前缀。您可以选择您喜欢的任何其他前缀 - 除了已经使用的前缀:wr
    • @SurenderThakran 如果它解决了您的问题,请考虑接受这个答案。我还建议您花一些时间阅读 XML 中的命名空间和前缀。
    【解决方案2】:

    元素在命名空间中,您将命名空间前缀误认为是命名空间。

    <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
    

    xmlns 属性将默认命名空间设置为其值。这个元素和任何其他没有命名空间前缀的元素都将在这个命名空间中。

    所以节点的实际内部地址是:

    {http://schemas.openxmlformats.org/package/2006/relationships}:Relationships 
    

    这就是为什么您在 xslt.xml 中定义自己的名称空间前缀的原因。为您添加该名称空间的注册 Xslt:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
    xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
    xmlns:rel="http://schemas.openxmlformats.org/package/2006/relationships"
    exclude-result-prefixes="w r rel">
    

    现在你可以使用它了:

    mergeddocx/rel:Relationships
    

    与元素节点不同,Xpath 没有默认命名空间。要寻址命名空间内的元素,您始终必须使用命名空间前缀。

    【讨论】:

    • 不,它没有用。但是 michael.hor257k 有效。感谢您的考虑:)
    • 它不起作用,因为r 前缀已经绑定到另一个命名空间。
    • 谢谢,没注意到。修正了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 2018-02-17
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多