简体   繁体   中英

How to get the attributes from an XML using XSLT?

This is the XML I am using from which I have to get the attributes values fort all the property name.

<?xml version="1.0" encoding="UTF-8"?>
<prodxml>
<prodxml><revisionNumber>05</revisionNumber><RosettaNet>
<Property name="Brush Thickness" ShortName="BRTHK" LongDesc="Brush Thickness" Code="1750" SubCode="" UCL="0.4400" LCL="0.4120"/>
<Property name="Bristle Diameter" ShortName="BAAA" LongDesc="Bristle Diameter" Code="306" SubCode="" UCL="0.005317" LCL="0.004806"/>
<Property name="Bristle Density" ShortName="BRD" LongDesc="Bristle Density" Code="305" SubCode="" UCL="96.2" LCL="72.0"/>
<Property name="Resin Density" ShortName="RDEN" LongDesc="Resin   Density" Code="1749" SubCode="" UCL="203" LCL="193"/>
<Property name="Brush Thickness Range" ShortName="BRTHR" LongDesc="Brush Thickness   Range" Code="2442" SubCode="" UCL="0.012" LCL="0"/>
<Property name="Bristle Diameter Range" ShortName="BAAD" LongDesc="Bristle Diameter   Range" Code="311" SubCode="" UCL="0.00105" LCL="0"/>
<Property name="Bristle Density Range" ShortName="BRDR" LongDesc="Bristle Density   Range" Code="310" SubCode="" UCL="29" LCL="0"/>
<Property name="Resin Density Range" ShortName="RDENR" LongDesc="Resin Density Range" Code="1753" SubCode="" UCL="20" LCL="0"/>
</RosettaNet>
<B2B_Customer>
<RecipientName>Intel</RecipientName>
</B2B_Customer>
</prodxml>
</prodxml>

This is the XSLT I am using, but unable to retrieve values. can anyone please help?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:template match="/">
      <xsl:element name="UCL" namespace="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">
         <xsl:value-of select="//RosettaNet/Property/@UCL" />
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

Thanks for the reply. Please find the expected output

<?xml version="1.0"?>
<UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">0.4400</UCL>
<UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">0.005317</UCL>
<UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">96.2</UCL>
<UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">203</UCL>
<UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">0.012</UCL>
<UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">0.00105</UCL>
<UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">29</UCL>
<UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">20</UCL>

You're not currently doing any iteration over the various nodes.

In XSLT this is done in two ways:

  • <xsl:for-each> - a traditional loop common in most languages

  • <xsl:apply-templates> - ie passing each node iteratively to a template for further processing

Here's an example with the latter:

<!-- root template -->
<xsl:template match="/">
    <xsl:apply-templates match='//RosettaNet/Property' />
</xsl:template>

<!-- match 'Property' nodes and output 'UCL' node for each one -->
<xsl:template match='Property'>
    <xsl:element name="UCL" namespace="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">
        <xsl:value-of select="@UCL" />
    </xsl:element>          
</xsl:template>

Within XSLT there are two basic paradigms for nodal access (which includes, among the other nodal types, the attributes in your question). These paradigms are referred to as " push " and " pull " for short.

" Push " involves using template matching to access the content in a more flow-like sort of manner. In other words, when the XSLT processor (eg Saxon) pushes a node through which is a match for a template (or templates), the template(s) is/are activated. (Let's stick with 'template' in the singular for now. If you have more than one template match, that gets into something called priority settings, which you should learn about, but which exceeds the scope of this question.) According to the "superman" of XSLT, Dr. Michael Kay, push is an all-too-underused paradigm, and more stylesheets ought to be written to take advantage of this, for many reasons.

" Pull " involves specifically yanking out, if you will, nodes/content that you need. The processor goes out and gets whatever you are looking for, if available - no templates required.

With regards to your particular problem, the following stylesheet (which is valid under XSLT 1.0 as well):

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

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

    <xsl:template match="/">
        <xsl:call-template name="pull_example"/>
        <!-- <xsl:call-template name="push_example"/> -->
    </xsl:template>

    <xsl:template name="pull_example">
        <!-- By "Pull" -->
        <Root>
            <xsl:for-each select="//Property/@UCL">
                <xsl:element name="UCL" namespace="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">
                    <xsl:value-of select="."/>
                </xsl:element>
            </xsl:for-each>
        </Root>
    </xsl:template>

    <xsl:template name="push_example">
        <!-- By "Push" -->
        <xsl:element name="Root">
            <xsl:apply-templates select="//Property/@UCL" mode="push_mode"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="//Property/@UCL" mode="push_mode">
        <xsl:element name="UCL" namespace="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

Applied to your data :

<?xml version="1.0" encoding="UTF-8"?>
<prodxml>
    <prodxml>
        <revisionNumber>05</revisionNumber>
        <RosettaNet>
            <Property name="Brush Thickness" ShortName="BRTHK" LongDesc="Brush Thickness" Code="1750" SubCode="" UCL="0.4400" LCL="0.4120"/>
            <Property name="Bristle Diameter" ShortName="BAAA" LongDesc="Bristle Diameter" Code="306" SubCode="" UCL="0.005317" LCL="0.004806"/>
            <Property name="Bristle Density" ShortName="BRD" LongDesc="Bristle Density" Code="305" SubCode="" UCL="96.2" LCL="72.0"/>
            <Property name="Resin Density" ShortName="RDEN" LongDesc="Resin   Density" Code="1749" SubCode="" UCL="203" LCL="193"/>
            <Property name="Brush Thickness Range" ShortName="BRTHR" LongDesc="Brush Thickness   Range" Code="2442" SubCode="" UCL="0.012" LCL="0"/>
            <Property name="Bristle Diameter Range" ShortName="BAAD" LongDesc="Bristle Diameter   Range" Code="311" SubCode="" UCL="0.00105" LCL="0"/>
            <Property name="Bristle Density Range" ShortName="BRDR" LongDesc="Bristle Density   Range" Code="310" SubCode="" UCL="29" LCL="0"/>
            <Property name="Resin Density Range" ShortName="RDENR" LongDesc="Resin Density Range" Code="1753" SubCode="" UCL="20" LCL="0"/>
        </RosettaNet>
        <B2B_Customer>
            <RecipientName>Intel</RecipientName>
        </B2B_Customer>
    </prodxml>
</prodxml>

Yields this output :

<?xml version="1.0" encoding="UTF-8"?>
<Root>
   <UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">0.4400</UCL>
   <UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">0.005317</UCL>
   <UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">96.2</UCL>
   <UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">203</UCL>
   <UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">0.012</UCL>
   <UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">0.00105</UCL>
   <UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">29</UCL>
   <UCL xmlns="x-schema:../Schema/ChemGasQualityCertificateSchema2001Jul.xml">20</UCL>
</Root>

(Please note that I wrapped your expected output in a <Root> tag, as otherwise, it would be considered non-well-formed .)

For all this and more, please see Push, Pull, Next! , which describes in detail the aspects/virtues of each methodology in more detail, including Michael Kay's take.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM