使用 Apache Xalan 对 XML 进行 XSLT 转换后缺少命名空间前缀

发布于 2024-11-09 03:52:00 字数 2287 浏览 3 评论 0原文

我有以下 XML:

<?xml version="1.0"?>
    <abc:Element1 xmlns:abc="http://..../resources/abc/v2/"
         ...>
         <abc:Element2>
            <abc:Element3s>
                 <abc:Element4 name="name1"
                               resourceRef="name2"/>
            </abc:Element3s>
         </abc:Element2>

         <abc:Resources>
            <abc:Resource xsi:type="abc:Something"
                          name="name2"/>
         </abc:Resources>
     </abc:Element1>   

... 和这个 XSLT 样式表:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:abc="http://.../resources/abc/v2/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:template match="/">
     <checker name="something">
       <xsl:for-each select="abc:Element1/abc:Element2/abc:Element3s/abc:Element4">
        <xsl:variable name="resource" select="@resourceRef"/>
        <xsl:variable name="xsiType"><xsl:value-of select="//abc:Resource[@name=$resource]/@xsi:type"/></xsl:variable>
        <xsl:choose>
            <xsl:when test="$xsiType='abc:Something'">
               ...
            </xsl:when>
            <xsl:otherwise>
               ...
            </xsl:otherwise>
         </xsl:choose>
       </xsl:for-each>
     </checker>
   </xsl:template>
</xsl:stylesheet>

我正在使用 XALAN 2.7.1 和 org.apache.xalan.xsltc.trax.TransformerFactoryImpl (也尝试过 org.apache.xalan.processor.TransformerFactoryImpl ->相同的结果)来转换 XML。

我希望以下行将 abc:Something 存储在变量 xsiType 中。

<xsl:variable name="xsiType"><xsl:value-of select="//abc:Resource[@name=$resource]/@xsi:type"/></xsl:variable>

但不幸的是只有Something(没有命名空间作为前缀)存储在xsiType中。我验证了这一点,因为

<xsl:when test="$xsiType='abc:Something'">

这不是真的。

我还使用 xsltproc 转换了 XMl,生成的 XML 看起来符合预期。因此,我希望输入的 XML/XSLT 样式表是正确的。我认为 Xalan 及其配置有问题。

有人可以帮忙吗?

I am having the following XML:

<?xml version="1.0"?>
    <abc:Element1 xmlns:abc="http://..../resources/abc/v2/"
         ...>
         <abc:Element2>
            <abc:Element3s>
                 <abc:Element4 name="name1"
                               resourceRef="name2"/>
            </abc:Element3s>
         </abc:Element2>

         <abc:Resources>
            <abc:Resource xsi:type="abc:Something"
                          name="name2"/>
         </abc:Resources>
     </abc:Element1>   

... and this XSLT stylesheet:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:abc="http://.../resources/abc/v2/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:template match="/">
     <checker name="something">
       <xsl:for-each select="abc:Element1/abc:Element2/abc:Element3s/abc:Element4">
        <xsl:variable name="resource" select="@resourceRef"/>
        <xsl:variable name="xsiType"><xsl:value-of select="//abc:Resource[@name=$resource]/@xsi:type"/></xsl:variable>
        <xsl:choose>
            <xsl:when test="$xsiType='abc:Something'">
               ...
            </xsl:when>
            <xsl:otherwise>
               ...
            </xsl:otherwise>
         </xsl:choose>
       </xsl:for-each>
     </checker>
   </xsl:template>
</xsl:stylesheet>

I am using XALAN 2.7.1 with org.apache.xalan.xsltc.trax.TransformerFactoryImpl (also tried with org.apache.xalan.processor.TransformerFactoryImpl -> same result) to transform the XML.

I expect the following line to store abc:Something in variable xsiType.

<xsl:variable name="xsiType"><xsl:value-of select="//abc:Resource[@name=$resource]/@xsi:type"/></xsl:variable>

but unfortunatley only Something (without namespace as prefix) is stored in xsiType. I verified this because

<xsl:when test="$xsiType='abc:Something'">

is not true.

I also transformed the XMl using xsltproc and the resulting XML looks as expected. Therefore, I expect the input XML/XSLT stylesheet to be correct. I assume something is wrong with Xalan and its configuration.

Can anyone help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寂寞清仓 2024-11-16 03:52:00

您的样本数据格式不正确,因此很难判断。这很可能是命名空间问题。这是输入和样式表的清理版本,用于提取所需的数据:

<?xml version="1.0"?>
<abc:Element1
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:abc="http://resources/abc/v2">
    <abc:Element2>
        <abc:Element3s>
            <abc:Element4 name="name1" resourceRef="name2"/>
        </abc:Element3s>
    </abc:Element2>
    <abc:Resources>
        <abc:Resource xsi:type="abc:Something" name="name2"/>
    </abc:Resources>
</abc:Element1>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:abc="http://resources/abc/v2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    exclude-result-prefixes="abc xsi"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:variable name="resource" select="'name2'"/>
        <xsl:variable name="type"
            select="//abc:Resource[@name=$resource]/@xsi:type"/>
        <checker name="{ $type }"/>
    </xsl:template>
</xsl:stylesheet>

这将产生:

<?xml version="1.0"?>
<checker name="abc:Something"/>

Your sample data is not well-formed, so it's difficult to tell. This is likely to be a namespace issues. Here's a sanitized version of your input and stylesheet that extracts the data you want:

<?xml version="1.0"?>
<abc:Element1
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:abc="http://resources/abc/v2">
    <abc:Element2>
        <abc:Element3s>
            <abc:Element4 name="name1" resourceRef="name2"/>
        </abc:Element3s>
    </abc:Element2>
    <abc:Resources>
        <abc:Resource xsi:type="abc:Something" name="name2"/>
    </abc:Resources>
</abc:Element1>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:abc="http://resources/abc/v2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    exclude-result-prefixes="abc xsi"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:variable name="resource" select="'name2'"/>
        <xsl:variable name="type"
            select="//abc:Resource[@name=$resource]/@xsi:type"/>
        <checker name="{ $type }"/>
    </xsl:template>
</xsl:stylesheet>

This will produce:

<?xml version="1.0"?>
<checker name="abc:Something"/>
◇流星雨 2024-11-16 03:52:00

在我看来,这似乎是 Xalan 特有的问题。然而,这可能是底层 XML 解析器的问题:Sun JDK 中的默认解析器有一些奇怪的错误,其中包括一些损坏属性值的错误。始终使用 Xalan 和 Xerces 的 Apache 版本,而不是 JDK 附带的版本。当然,如果您使用 Xalan,那么切换到 Saxon 的成本几乎为零,这为您提供了 XSLT 2.0 的所有优势。

It looks to me like a problem specific to Xalan. It could however be a problem with the underlying XML parser: the default parser in th Sun JDK has some weird bugs including some that corrupt attribute values. Always use the Apache versions of Xalan and Xerces rather than the versions that come with the JDK. And of course, if you're using Xalan then it's almost zero cost to switch to Saxon, which gives you all the benefits of XSLT 2.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文