开发者

How to select elements in namespace scope and get rid of empty default namespace in the output

开发者 https://www.devze.com 2023-03-11 04:15 出处:网络
I need to transform the following input file <?xml version=\"1.0\"?> <soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\"

I need to transform the following input file

<?xml version="1.0"?>
<soap:Envelope 
    xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope">
        <wsa:Action>http://worksite.imanage.com/SearchDocumentsResponse</wsa:Action>
        <wsa:MessageID>urn:uuid:b9b79a0f-b4de-4686-9c54-51c5a7f99331</wsa:MessageID>
        <wsa:RelatesTo>urn:uuid:8e88f531-8369-4557-80bf-e8a9835d8eb3</wsa:RelatesTo>
        <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
        <wsse:Security>
            <wsu:Timestamp wsu:Id="Timestamp-ea526ce6-ca66-4aaf-aae9-cf2fe8d5cbad">
                <wsu:Created>2011-06-01T07:09:20Z</wsu:Created>
                <wsu:Expires>2011-06-01T07:14:20Z</wsu:Expires>
            </wsu:Timestamp>
        </wsse:Security>
    </env:Header>
    <soap:Body>
        <SearchDocumentsResult xmlns="http://worksite.imanage.com">
            <Documents>
                <Document>
                    <ObjectID>!nrtdms:0:!session:PTHT096:!database:Technical:!document:803226,1:</ObjectID>
                    <Database>Technical</Database>
                    <Profile>
                        <ProfileItem>
                            <AttributeID>imProfileDocNum</AttributeID>
                            <Value>803226</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <Attr开发者_如何学PythonibuteID>imProfileDescription</AttributeID>
                            <Value>TC-D60-1087 - Compressor C-301C Installation Work Platform General Arrangement</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileVersion</AttributeID>
                            <Value>1</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileCustom3</AttributeID>
                            <Value>CV</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileDatabase</AttributeID>
                            <Value>Technical</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileExtension</AttributeID>
                            <Value>ACROBAT</Value>
                        </ProfileItem>
                    </Profile>
                </Document>
            </Documents>
        </SearchDocumentsResult>
    </soap:Body>
</soap:Envelope>

into the following output file

<?xml version="1.0"?>
<soap:Envelope 
    xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope">
        <wsa:Action>http://worksite.imanage.com/SearchDocumentsResponse</wsa:Action>
        <wsa:MessageID>urn:uuid:b9b79a0f-b4de-4686-9c54-51c5a7f99331</wsa:MessageID>
        <wsa:RelatesTo>urn:uuid:8e88f531-8369-4557-80bf-e8a9835d8eb3</wsa:RelatesTo>
        <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
        <wsse:Security>
            <wsu:Timestamp wsu:Id="Timestamp-ea526ce6-ca66-4aaf-aae9-cf2fe8d5cbad">
                <wsu:Created>2011-06-01T07:09:20Z</wsu:Created>
                <wsu:Expires>2011-06-01T07:14:20Z</wsu:Expires>
            </wsu:Timestamp>
        </wsse:Security>
    </env:Header>
    <soap:Body>
        <SearchDocumentsResult xmlns="http://worksite.imanage.com">
            <Documents>
                <Document>
                    <ObjectID>!nrtdms:0:!session:PTHT096:!database:Technical:!document:803226,1:</ObjectID>
                    <Database>Technical</Database>
                    <Profile>
                        <ProfileItem>
                            <AttributeID>imProfileDocNum</AttributeID>
                            <Value>803226</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileDescription</AttributeID>
                            <Value>TC-D60-1087 - Compressor C-301C Installation Work Platform General Arrangement</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileVersion</AttributeID>
                            <Value>1</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileCustom3</AttributeID>
                            <Value>CV</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileDatabase</AttributeID>
                            <Value>Technical</Value>
                        </ProfileItem>
                        <ProfileItem>
                            <AttributeID>imProfileExtension</AttributeID>
                            <Value>pdf</Value>
                        </ProfileItem>
                    </Profile>
                </Document>
            </Documents>
        </SearchDocumentsResult>
    </soap:Body>
</soap:Envelope>

I have written the following stylesheet to do the job

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet 
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
xmlns:soap = "http://www.w3.org/2003/05/soap-envelope"
    xmlns:w = "http://worksite.imanage.com"
exclude-result-prefixes="#all"
version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="element()">
    <xsl:copy>
    <xsl:apply-templates select="@*,node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="attribute()|text()|comment()|processing-instruction()">
    <xsl:copy/>
</xsl:template>

<xsl:template match = "//w:ProfileItem[6]/child::w:Value">        
    <xsl:call-template name="changeDocumentExtension"/>
</xsl:template>

<xsl:template name = "changeDocumentExtension">

    <xsl:variable 
    name="iManageExtension"
    as = "xs:string"
    select="//w:AttributeID[. = 'imProfileExtension']/following::w:Value"
    />

    <xsl:choose>
    <xsl:when test="$iManageExtension eq 'ACROBAT'">
        <Value>pdf</Value>
    </xsl:when>
    <xsl:when test="$iManageExtension eq 'ANSI'">
        <Value>txt</Value>
    </xsl:when>
    <xsl:when test="$iManageExtension eq 'EXCEL'">
        <Value>xsl</Value>
    </xsl:when>
    <xsl:when test="$iManageExtension eq 'EXCELX'">
        <Value>xslx</Value>
    </xsl:when>
    <xsl:when test="$iManageExtension eq 'PDF230'">
        <Value>pdf</Value>
    </xsl:when>
    <xsl:when test="$iManageExtension eq 'WORD'">
        <Value>doc</Value>
    </xsl:when>
    <xsl:when test="$iManageExtension eq 'WORDX'">
        <Value>docx</Value>
    </xsl:when>
    <xsl:when test="$iManageExtension eq 'WORDXT'">
        <Value>docx</Value>
    </xsl:when>
    </xsl:choose>               

</xsl:template>      

</xsl:stylesheet>

This is the output that I get

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope 
    xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <env:Header xmlns:env="http://www.w3.org/2003/05/soap-envelope">
    <wsa:Action>http://worksite.imanage.com/SearchDocumentsResponse</wsa:Action>
    <wsa:MessageID>urn:uuid:b9b79a0f-b4de-4686-9c54-51c5a7f99331</wsa:MessageID>
    <wsa:RelatesTo>urn:uuid:8e88f531-8369-4557-80bf-e8a9835d8eb3</wsa:RelatesTo>
    <wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
    <wsse:Security>
        <wsu:Timestamp wsu:Id="Timestamp-ea526ce6-ca66-4aaf-aae9-cf2fe8d5cbad">
        <wsu:Created>2011-06-01T07:09:20Z</wsu:Created>
        <wsu:Expires>2011-06-01T07:14:20Z</wsu:Expires>
        </wsu:Timestamp>
    </wsse:Security>
    </env:Header>
    <soap:Body>
    <SearchDocumentsResult xmlns="http://worksite.imanage.com">
        <Documents>
        <Document>
            <ObjectID>!nrtdms:0:!session:PTHT096:!database:Technical:!document:803226,1:</ObjectID>
            <Database>Technical</Database>
            <Profile>
            <ProfileItem>
                <AttributeID>imProfileDocNum</AttributeID>
                <Value>803226</Value>
            </ProfileItem>
            <ProfileItem>
                <AttributeID>imProfileDescription</AttributeID>
                <Value>TC-D60-1087 - Compressor C-301C Installation Work Platform General Arrangement</Value>
            </ProfileItem>
            <ProfileItem>
                <AttributeID>imProfileVersion</AttributeID>
                <Value>1</Value>
            </ProfileItem>
            <ProfileItem>
                <AttributeID>imProfileCustom3</AttributeID>
                <Value>CV</Value>
            </ProfileItem>
            <ProfileItem>
                <AttributeID>imProfileDatabase</AttributeID>
                <Value>Technical</Value>
            </ProfileItem>
            <ProfileItem>
                <AttributeID>imProfileExtension</AttributeID>
                <Value xmlns="">pdf</Value>
            </ProfileItem>
            </Profile>
        </Document>
        </Documents>
    </SearchDocumentsResult>
    </soap:Body>
</soap:Envelope>

I would like to get some help with the following issues:

  1. There is an unwanted xmlns="" element in the output that can't be removed using the exclude-result-prefixes attribute. I don't know how to get rid of it.

  2. The stylesheet has two long XPaths. They do the job and point to the right elements but I can't help but cringe every time I look at them. If someone could offer a shorter, cleaner alternative, I'd really appreciate it.


Simplify XPath

I suggest you to include in your transform a declaration with prefix for the default namespaces. For example for

 <SearchDocumentsResult xmlns="http://worksite.imanage.com">

you can add w prefix in the stylesheet element:

<xsl:stylesheet 
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
xmlns:soap = "http://www.w3.org/2003/05/soap-envelope"
xmlns:w = "http://worksite.imanage.com"
exclude-result-prefixes="#all"
version="2.0">

This will make easier for you select elements in the namespace, thus making possible to avoid XPath match against namespace-uri() and simplifying your XPath.

About XPath, how much your selection must be absolute? For example the following worked the same for me:

"/soap:Envelope/soap:Body[1]/w:SearchDocumentResult/*[1]/*[1]/*[1]/*[6]/*[1]"

But you can also use:

"/soap:Envelope/soap:Body[1]/w:SearchDocumentResult//w:Value[1]"

Remove Empty Namespace

To get rid of the empty namespace appearing in the Value element, you need to fix your stylesheet so that each Value element is correctly located in the namespace. Example:

<xsl:when test="$iManageExtension eq 'ACROBAT'">
  <xsl:element 
       name="Value" 
       namespace="http://worksite.imanage.com">
       pdf
  </xsl:element>

In this way the system will usually output the element without the namespace.


Further Note about Simplifying XPath

Note that in certain situations, where mostly you want to manage a specific namespace, you can simply do:

<xsl:stylesheet 
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
xmlns:soap = "http://www.w3.org/2003/05/soap-envelope"
exclude-result-prefixes="#all"
xpath-default-namespace="http://worksite.imanage.com"
version="2.0">

and work without namespace prefix.


The following stylesheet does the job:

    <?xml version="1.0" encoding="UTF-8"?>

    <xsl:stylesheet 
        xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
        xmlns:xs = "http://www.w3.org/2001/XMLSchema"   
        xmlns:w = "http://worksite.imanage.com"      
        exclude-result-prefixes="#all"
        version="2.0">

    <xsl:output indent="yes"/>

    <xsl:template match="element()">
        <xsl:copy>
            <xsl:apply-templates select="@*, node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="attribute()|text()|comment()|processing-instruction()">
        <xsl:copy/>
    </xsl:template>

    <xsl:template match = "//w:ProfileItem[6]/child::w:Value">
        <xsl:element name="{local-name()}" namespace="http://worksite.imanage.com">
            <xsl:call-template name="changeDocumentExtension"/>
        </xsl:element>
    </xsl:template>

    <xsl:template name="changeDocumentExtension">

        <xsl:variable 
            name="iManageExtension" 
            as="xs:string"
            select="//w:AttributeID[. = 'imProfileExtension']/following::w:Value"/>

        <xsl:choose>
            <xsl:when test="$iManageExtension eq 'ACROBAT'"> pdf </xsl:when>
            <xsl:when test="$iManageExtension eq 'ANSI'"> txt </xsl:when>
            <xsl:when test="$iManageExtension eq 'EXCEL'"> xsl </xsl:when>
            <xsl:when test="$iManageExtension eq 'EXCELX'"> xslx </xsl:when>
            <xsl:when test="$iManageExtension eq 'HTML'"> htm </xsl:when>
            <xsl:when test="$iManageExtension eq 'JPEG'"> jpg </xsl:when>
            <xsl:when test="$iManageExtension eq 'PDF230'"> pdf </xsl:when>
            <xsl:when test="$iManageExtension eq 'PPT'"> ppt </xsl:when>
            <xsl:when test="$iManageExtension eq 'PPTX'"> pptx </xsl:when>
            <xsl:when test="$iManageExtension eq 'WORD'"> doc </xsl:when>
            <xsl:when test="$iManageExtension eq 'WORDX'"> docx </xsl:when>
            <xsl:when test="$iManageExtension eq 'WORDXT'"> docx </xsl:when>
        </xsl:choose>

    </xsl:template>      

</xsl:stylesheet>
0

精彩评论

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