开发者

xslt - refer to a document in xsl:element

开发者 https://www.devze.com 2023-02-03 15:14 出处:网络
i want to refer to an external xml in xls in an element <xsl:element name=\"{document(\'mapping.xml\', /)/mappings/column/[@id=name()]}\" >

i want to refer to an external xml in xls in an element

<xsl:element name="{document('mapping.xml', /)/mappings/column/[@id=name()]}" >

Is this possible?

Update

mapping.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings>
      <columns>
        <column id="path">path</column>
      </columns>
</mappings>

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:dms="http://www.news.at/dms">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

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

    <xsl:template match="/">
        <xsl:element name="document">
            <xsl:for-开发者_StackOverflow社区each select="document/*">

            <xsl:element name=
  "{$Mapping/mappings/columns/column[@id = name(current())]}" />


                <xsl:element name="item" >

                <xsl:attribute name="id">
                <xsl:if test="not($Mapping/mappings/columns/column[@id= name(current())])">
                    <xsl:message>Markup Error: no id attribute in <xsl:value-of select="name(current())" /></xsl:message>
               </xsl:if>        
                        <xsl:value-of select="$Mapping/mappings/columns/column[@id= name(current())]" /></xsl:attribute>
                    <xsl:value-of select="text()" />
                </xsl:element>
            </xsl:for-each>     
        </xsl:element>
    </xsl:template>


</xsl:stylesheet>

input.xml

<?xml version="1.0" encoding="UTF-8" ?>
<document>
   <path>sdfsdfsdf</path>
</document>

Thank you!


Yes, absolutely. Like this, though:

<xsl:element name="{normalize-space(
  document('mapping.xml', /)/mappings/column[@id=name(current())]
)}" >

In plain English: This will select any <column> within /mappings whose @id is equal to the name of the current element in XSLT. The text value of this column will be trimmed via normalize-space() and becomes the new <xsl:element> name.

(Note that comumn[@id=name()] means "any column whose @id is equal to its name", and therefore only matches <column id="column">. The current() function is necessary to do what you want.)

It would help, though, to save the document into a global variable first:

<!-- at the <xsl:stylesheet> level... -->
<xsl:variable name="mappings" 
  select="document('mapping.xml', /)/mappings/column" 
/>

<!-- later, anywhere... -->
<xsl:element name="{ normalize-space($mappings[@id=name(current())]) }" >


i want to refer to an external xml in xls in an element

<xsl:element name=
 "{document('mapping.xml', /)/mappings/column/[@id=name()]}" >

Yes, the name attribute of the <xsl:element> instruction allowas AVTs (Attribute-Value-Template s)

The provided code has a number of problems:

  1. There is an obvious syntax error in the code you provided:

    document('mapping.xml', /)/mappings/column/[@id=name()]

is not a syntactically legal XPath expression. The last location step lacks a node-test and only has a predicate.

.2. There is nothing in the above expression that relates to the current node in the original XML document. I guess, the predicate

[@id=name()]

should actually be something like:

[@id=name(current())]

So, my guess is that you may want something like:

 <xsl:element name=
  "{document('mapping.xml', /)/mappings/column[@id=name(current())]}" >

There could be an additional, third problem: (confirmed in a comment by the OP to be the real problem):

The expression specified as AVT in the name attribute above may have a string value that is not a syntactically legal QName. Examples of sych illegal values: 123 or A B

In this case there are different possible solutions:

  • Use the string value of another node (change the XPath expression).
  • Transform the offending characters to an allowed character:

...

concat(
       translate(substring(yourExpression,1,1), 
                 $illegalFirstCharacters, 
                 '________________'),
       translate(substring(yourExpression,2),
                 $illegalCharacters,
                 '________________')
       )

where $illegalFirstCharacters is a variable defined to contain all possible characters that may occur as a first character and that are not allowed as a first character of a QName

and $illegalCharacters is a variable defined to contain all possible characters that may occur as after the first character and that are not allowed as in a QName after its first character.

Essentially, $illegalFirstCharacters is the concatenation of $illegalCharacters and the string "0123456789".

The last argument of translate() above must be long enough to accomodate one _ for each possible illegal character.

This transformation into a valid QName can be expressed much more easily in XPath 2.0 (XSLT 2.0) using regular expressions.

This solution, of course, should be exercised with caution, because, depending on the actual data, it is possible for two different values that contain illegal QNAme characters, to be converted to the same QName.

0

精彩评论

暂无评论...
验证码 换一张
取 消