Selecting/matching elements in a namespace

2020-02-15 08:49发布

I have a xml and xsl that need to generate another xml, but because of 'xmlns', it generates an empty xml. Without 'xmlns' in the root of XML, it works fine. The following XSL is not a complete version yet. I need to put more logic into it, but I am stuck in here, because of 'xmlns'.

I am using Java API to generate another XML with this XML and XSL. Can somebody tell me why it can't match the element because of the xmlns and how to fix it?

Thanks.

XML:

<?xml version="1.0" encoding="UTF-8"?>
 <config xmlns="http://xmlns.company.com/config">
   <subi-config>
     <primary-data-source>Repository</primary-data-source>
     <instance>
       <name>agent1</name>
       <address>localhost</address>
       <port>8080</port>
       <admin-username>admin</admin-username>
     </instance>
   </subi-config>
 </config>

XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://xmlns.company.com/config">

  <xsl:output method="xml" encoding="UTF-8"  indent="yes"/>


  <xsl:template match="/">
        <xsl:apply-templates  select="config"/>
  </xsl:template>


    <xsl:template  match="config">
        <config>
          <sub-config>
        <primary-data-source><xsl:value-of select="sub-config/primary-data-source"/></primary-data-source>
            <xsl:apply-templates select="sub-config"/>
      </sub-config>
    </config>

</xsl:template>


<xsl:template match="sub-config">
        <xsl:for-each select="instance">

            <instance>
              <name><xsl:value-of select="name"/></name>
              <address><xsl:value-of select="address"/></address>
                <port><xsl:value-of select="port"/></port>
              <admin-username><xsl:value-of select="admin-username"/></admin-username>
            </instance>

        </xsl:for-each>

</xsl:template>

标签: xml xslt
2条回答
ら.Afraid
2楼-- · 2020-02-15 09:32

Use xsl:element with namespace attribute

<xsl:template  match="config">
  <xsl:element namespace="http://xmlns.company.com/config" name="config">
     <sub-config>
       <primary-data-source><xsl:value-of select="sub-config/primary-data-source"/></primary-data-source>
       <xsl:apply-templates select="sub-config"/>
    </sub-config>
  </xsl:element>

</xsl:template>

It will create element with computed name( Static for us ) and allow to add namespace attribute

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2020-02-15 09:33

You need to assign a prefix to the namespace and use that prefix when addressing the elements of the source XML:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cfg="http://xmlns.company.com/config"
exclude-result-prefixes="cfg"> 

<xsl:output method="xml" encoding="UTF-8"  indent="yes"/>

<xsl:template match="/">
    <xsl:apply-templates  select="cfg:config"/>
</xsl:template>

<xsl:template  match="cfg:config">
    <config>
        <sub-config>
            <primary-data-source>
                <xsl:value-of select="cfg:sub-config/cfg:primary-data-source"/>
            </primary-data-source>
            <xsl:apply-templates select="cfg:sub-config"/>
        </sub-config>
    </config>
</xsl:template>

<xsl:template match="cfg:sub-config">
    <xsl:for-each select="cfg:instance">
        <instance>
            <name><xsl:value-of select="cfg:name"/></name>
            <address><xsl:value-of select="cfg:address"/></address>
            <port><xsl:value-of select="cfg:port"/></port>
            <admin-username><xsl:value-of select="cfg:admin-username"/></admin-username>
        </instance>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Note that sub-config and subi-config are two different things.

查看更多
登录 后发表回答