xml - 具有默认命名空间的 XML 文件上的 XSLT。带有 'artificial' 前缀的 Xpath

标签 xml xslt xpath

我有一个带有默认命名空间的大型数据库 XML 文件,要使用 XSLT 进行转换。这是一个最小的例子。

该文件称为 server.xml。它包含不正确的数据。

<?xml version="1.0" encoding="UTF-8"?>
<bookstore xmlns="http://www.mybook.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <book author="Incorrect_Author">
    <title>Correct_Title</title>  
 </book>
</bookstore>

需要通过匹配另一个 XML 文件中的书名来将作者更改为正确的值。

第二个 xml 文件称为 client.xml。它包含该书的正确作者姓名。
<?xml version="1.0" encoding="UTF-8"?>
<bookstore xmlns="http://www.mybook.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <book author="Correct_Author">
    <title>Correct_Title</title>  
    <additionalstuff/>
 </book>
</bookstore>

但是,它也有我不想要的附加信息。所以我想根据客户端修改服务器,按书名匹配。

我编写了以下 XSLT(基于 this answer )。如果我人为地删除我的 xml 文件中的默认 xmlns,它就可以完成这项工作。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:param name="clientXml" select="'client.xml'" />

<xsl:variable name="client" select="document($clientXml)//book" />

<xsl:template match="book/@author">
    <xsl:attribute name="author">
        <xsl:value-of select="$client[child::title=current()/../title]/@author" />
    </xsl:attribute>
</xsl:template>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

但是,我需要它来处理文件(包含默认 ns)。我知道这是一个当前问题,所以我根据找到的答案尝试了以下代码。它不起作用。 XPath 前缀有问题吗?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:v="http://www.mybook.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="v" >

 <xsl:output method="xml" indent="yes"/>

 <xsl:param name="clientXml" select="'client.xml'" />

 <xsl:variable name="client" select="document($clientXml)//v:book" />

 <xsl:template match="v:book/@author">
    <xsl:attribute name="author">
        <xsl:value-of select="$client[child::title=current()/../title]/@author" />
    </xsl:attribute>
 </xsl:template>

 <xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

最佳答案

XPaths,包括那些在 XSLT 中使用的,是命名空间感知的......不幸的是,至少在 1.0 版本的规范中不支持默认命名空间的概念。要匹配命名空间节点,您必须在样式表的路径中使用正确绑定(bind)的前缀,即使您在输入文档中没有这样做。

关于xml - 具有默认命名空间的 XML 文件上的 XSLT。带有 'artificial' 前缀的 Xpath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23984353/

相关文章:

xml - 使用 xpath 包含忽略重音符号

xml - 如何将特定属性转换为复杂 XML 中的元素

javascript - JavaScript block 内的 XSL 标记

xml - 关于xmlns的问题

javascript - 如何获取父元素文本并删除子元素文本 selenium c#?

javascript - 搜索 XML 文件

大量使用运算符重载的 C++ XML 库

regex - 在bash中替换xml中的标签

通过 XSL 具有交替行颜色的 HTML 表格

xml - 关于根节点的简单 XPath 问题