使用命名空间

时间:2015-06-05 20:23:19

标签: xml xslt xpath

我尝试转换XML文档并修改单个元素的属性,但如果根元素具有命名空间属性,则不会应用转换。只需删除xmlns就可以正常使用我的代码。

我的XML:

<?xml version="1.0"?>
<BIDomain xmlns="http://www.oracle.com/biee/bi-domain">
  <BIInstance name="coreapplication">
    <SecurityOptions sslManualConfig="false" sslEnabled="false" ssoProvider="Custom" ssoEnabled="false">
      <SecurityService>
        <EndpointURI>bisecurity/service</EndpointURI>
      </SecurityService>
    </SecurityOptions>
  </BIInstance>
</BIDomain>

使用的XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" standalone="yes" />

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

  <!-- Add the new attributes -->
  <xsl:template match="SecurityOptions">
    <xsl:copy>
            <xsl:attribute name="ssoProviderLogoffURL"/>
            <xsl:attribute name="ssoProviderLogonURL"/>
            <xsl:attribute name="sslVerifyPeers">
                <xsl:value-of select="'false'" />
            </xsl:attribute>           
            <xsl:apply-templates  select="node() | @*"/>
        </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

最终结果是相同的XML。如果我从根元素中删除命名空间定义     <BIDomain xmlns="http://www.oracle.com/biee/bi-domain">转换正常应用。我假设我做错了,并且命名空间属性干扰了匹配。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您尝试匹配的元素位于命名空间(默认命名空间)中,因此您需要在XSLT中正确使用命名空间:

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:bi="http://www.oracle.com/biee/bi-domain">
                  <!--   ^----- here   -->
  <xsl:output method="xml" version="1.0" standalone="yes" />

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

  <!-- Add the new attributes -->
                <!--   v------- and here   -->
  <xsl:template match="bi:SecurityOptions">
    <xsl:copy>
      <xsl:attribute name="ssoProviderLogoffURL"/>
      <xsl:attribute name="ssoProviderLogonURL"/>
      <xsl:attribute name="sslVerifyPeers">
        <xsl:value-of select="'false'" />
      </xsl:attribute>           
      <xsl:apply-templates  select="node() | @*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:2)

xmlns的工作原理是所有节点都从父节点继承xmlns属性。除非另有说明,否则当文档根目录包含时,这意味着什么 xmlns="http://www.oracle.com/biee/bi-domain" 它将该命名空间应用于所有子树。

因此,您实际上正在寻找名称空间为SecurityOptions的{​​{1}}代码。

这意味着您的XSLT实际上需要具有以下内容:

"http://www.oracle.com/biee/bi-domain"

位于顶部,模板匹配如下所示:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tmp="http://www.oracle.com/biee/bi-domain">

注意tmp:匹配xmlns:tmp;这称为命名空间前缀,允许xml将<xsl:template match="tmp:SecurityOptions"> 的小字符串与tmp的大字符串匹配。