[xslt] Transformation result DOM document does not honor xml:id



The result DOM document of a transformation does not honor the automatic
ID-ness of an xml:id attribute. My feeling, which may of course be
wrong, is that it should. But unlike Daniel, I wasn't among the editors
of the xml:id specification.

http://www.w3.org/TR/xml-id/

So should xml:id be honored in this case, or shouldn't it?

To demonstrate, a simple stylesheet and two scripts to choose from,
one in PHP, one in Perl. First, some version information.

Michael Ludwig

milu colinux:~ > perl libxml2-version.pl
libxml compiled 20702
libxml runtime  20702
libxml version 2.7.2
XML::LibXML version 1.68
libxslt compiled 10124
libxslt runtime  10124
libxslt version 1.1.24
XML::LibXSLT version 1.68

PHP links to the same C library version of LibXML2 and LibXSLT.

milu colinux:~/Werkstatt/php > expand -t2 xmlid-xsl.xsl
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:template match="/">
    <Urmel>
      <div xml:id="nav">Hu</div>
      <div>
        <xsl:attribute name="xml:id">cont</xsl:attribute>
        <xsl:text>Bla</xsl:text>
      </div>
    </Urmel>
  </xsl:template>
</xsl:stylesheet>

milu colinux:~/Werkstatt/php > expand -t2 xmlid-xsl.php
Ich will aus einem Dokument ein ID-Element pflücken und dann den
entsprechenden Teilbaum serialisieren. Geht das auch, wenn das
Dokument aus XSL kommt?
<?php

function domtest( $doc) {
  echo "----------\n", $doc->saveXML(), "\n";
  foreach ( array( 'nav', 'cont') as $id ) {
    $elm = $doc->getElementById( $id);
    echo "Element fuer $id ist: "; var_dump( $elm);
    echo $doc->saveXML( $elm), "\n";
  }
}

$indoc = new DOMDocument;
$indoc->loadXML( '<Urmel/>'); # source document

$xsldoc = new DOMDocument;
$xsldoc->load( $argv[1]); # stylesheet
$xsl = new XSLTProcessor;
$xsl->importStyleSheet( $xsldoc); # processor

$resdoc = $xsl->transformToDoc( $indoc); # XSLT result document
domtest( $resdoc); # xml:id not recognized

$resstr = $xsl->transformToXml( $indoc); # serialize
$resdoc2 = new DOMDocument;
$resdoc2->loadXML( $resstr); # and parse again
domtest( $resdoc2); # xml:id recognized

milu colinux:~/Werkstatt/php > php xmlid-xsl.php xmlid-xsl.xsl
Ich will aus einem Dokument ein ID-Element pflücken und dann den
entsprechenden Teilbaum serialisieren. Geht das auch, wenn das
Dokument aus XSL kommt?
----------
<?xml version="1.0"?>
<Urmel><div xml:id="nav">Hu</div><div xml:id="cont">Bla</div></Urmel>

Element fuer nav ist: NULL
<?xml version="1.0"?>
<Urmel><div xml:id="nav">Hu</div><div xml:id="cont">Bla</div></Urmel>

Element fuer cont ist: NULL
<?xml version="1.0"?>
<Urmel><div xml:id="nav">Hu</div><div xml:id="cont">Bla</div></Urmel>

----------
<?xml version="1.0"?>
<Urmel><div xml:id="nav">Hu</div><div xml:id="cont">Bla</div></Urmel>

Element fuer nav ist: object(DOMElement)#6 (0) {
}
<div xml:id="nav">Hu</div>
Element fuer cont ist: object(DOMElement)#7 (0) {
}
<div xml:id="cont">Bla</div>

milu colinux:~/Werkstatt/php > expand -t2 xmlid-xsl.pl
use strict;
use warnings;
use XML::LibXML;
use XML::LibXSLT;

sub domtest {
  my $doc = shift;
  print "\n", ref $doc, "\n";
  print "----------\n", $doc->toString, "\n";
  for my $id ( qw(nav cont) ) {
    my $elm = $doc->getElementById( $id);
    printf "Element fuer $id ist: %s\n", $elm || '-';
    next unless $elm;
    my $doc2 = XML::LibXML::Document->new;
    $doc2->setDocumentElement( $doc2->importNode( $elm, 1));
    print $doc2->toString, "\n";
  }
}

my $xsl_file = shift or die 'XSL-Datei!';

my $parser = XML::LibXML->new;

my $indoc = $parser->parse_string( '<Urmel/>'); # source document

my $xsldoc = $parser->parse_file( $xsl_file);
my $xsl = XML::LibXSLT->new;
my $proc = $xsl->parse_stylesheet( $xsldoc); # processor

my $resdoc = $proc->transform( $indoc); # XSLT result document
domtest( $resdoc); # xml:id not recognized

my $resstr = $proc->output_string( $resdoc); # serialize
my $resdoc2 = $parser->parse_string( $resstr); # and parse again
domtest( $resdoc2); # xml:id recognized

milu colinux:~/Werkstatt/php > perl xmlid-xsl.pl xmlid-xsl.xsl

XML::LibXML::Document
----------
<?xml version="1.0"?>
<Urmel><div xml:id="nav">Hu</div><div xml:id="cont">Bla</div></Urmel>

Element fuer nav ist: -
Element fuer cont ist: -

XML::LibXML::Document
----------
<?xml version="1.0"?>
<Urmel><div xml:id="nav">Hu</div><div xml:id="cont">Bla</div></Urmel>

Element fuer nav ist: XML::LibXML::Element=SCALAR(0x8372b8c)
<?xml version="1.0"?>
<div xml:id="nav">Hu</div>

Element fuer cont ist: XML::LibXML::Element=SCALAR(0x8372bd4)
<?xml version="1.0"?>
<div xml:id="cont">Bla</div>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]