Cross-reference issue and XML element extension in XSLT using document ()

I'm a little new to XML, and I have a problem when I have an XML document that has been generated for which the list of attributes for some elements is incomplete. I am trying to implement an XSLT stylesheet that cross-references it with a main document (which has default values ​​for all attributes) to fill in any missing attributes with default values.

For example, take the following incomplete XML document:

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar label="two" index="2"/>
</foo>

The bar element has the missing "type" attribute, which I would like to fill in with the default value from the following main document according to the value of "label":

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar label="one" index="1" type="type1"/>
  <bar label="two" index="2" type="type2"/>
  <bar label="three" index="3" type="type3"/>
</foo>

Desired Result:

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar label="two" index="2" type="type2"/>
</foo>

XSLT , "document()" XPath :

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

  <xsl:variable name="master" select="document('master.xml')"/>

  <!-- Template matching 'root' of XML document -->
  <xsl:template match="/">
    <xsl:apply-templates select="foo"/>
  </xsl:template>

  <!-- Template for generating 'foo' element -->
  <xsl:template match="foo">
    <foo>
      <xsl:apply-templates select="bar"/>
    </foo>
  </xsl:template>

  <!-- Template for generating 'bar' element -->
  <xsl:template match="bar">
    <bar label="{@label}" index="{@index}" type="{$master/foo/bar[@label=@label][1]/@type}"/>
  </xsl:template>

</xsl:stylesheet>

, , "type" "bar" "one", "two":

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar label="two" index="2" type="type1"/>
</foo>

, XPath "bar", , , .

, ?

+3
1

:

<bar label="{@label}" index="{@index}" 
     type="{$master/foo/bar[@label=@label][1]/@type}"/> 

, label bar - :

<bar label="{@label}" index="{@index}" 
     type="{$master/foo/bar[true()][2]/@type}"/> 

, :

<bar label="{@label}" index="{@index}" 
     type="{$master/foo/bar[1]/@type}"/> 

, .

. XSLT current():

<bar label="{@label}" index="{@index}" 
     type="{$master/foo/bar[@label=current()/@label][4]/@type}"/> 

( URL- master.xml, ):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

      <xsl:variable name="master" select=
      "document('file:///c:/temp/delete/master.xml')"/>

      <!-- Template matching 'root' of XML document -->
      <xsl:template match="/">
        <xsl:apply-templates select="foo"/>
      </xsl:template>

      <!-- Template for generating 'foo' element -->
      <xsl:template match="foo">
        <foo>
          <xsl:apply-templates select="bar"/>
        </foo>
      </xsl:template>

      <!-- Template for generating 'bar' element -->
      <xsl:template match="bar">
        <bar label="{@label}" index="{@index}"
        type="{$master/foo/bar[@label=current()/@label][5]/@type}"/>
      </xsl:template>
</xsl:stylesheet>

, XML-:

<foo>
    <bar label="two" index="2"/>
</foo>

, :

<foo><bar label="two" index="2" type="type2"/></foo>

II. , :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kTypeByLabel" match="@type" use="../@label"/>

      <xsl:variable name="master" select=
      "document('file:///c:/temp/delete/master.xml')"/>

      <!-- Template matching 'root' of XML document -->
      <xsl:template match="/">
        <xsl:apply-templates select="foo"/>
      </xsl:template>

      <!-- Template for generating 'foo' element -->
      <xsl:template match="foo">
        <foo>
          <xsl:apply-templates select="bar"/>
        </foo>
      </xsl:template>

      <!-- Template for generating 'bar' element -->
      <xsl:template match="bar">
        <xsl:variable name="vCurrent" select="."/>
        <xsl:variable name="vDefault">
          <xsl:for-each select="$master">
            <xsl:value-of select=
                "key('kTypeByLabel', $vCurrent/@label)"/>
          </xsl:for-each>
        </xsl:variable>

        <bar label="{@label}" index="{@index}" type="{$vDefault}"/>
      </xsl:template>
</xsl:stylesheet>

( ) XML- (), , :

<foo>
   <bar label="two" index="2" type="type2"/>
</foo>
+2

All Articles