2012-03-29 7 views
1

名前空間URIの一部を別の文字列に置き換えようとすると、入力されたSOAPメッセージがあります。 URI全体を別のURIに置き換えることはできますが、既存のURIを変更することはできません。私は 'OLDSTRING'を探して 'NEWSTRING'と置き換える必要があります。私はSOAPメッセージでXSLTを使用してnamespace uriを置き換えます。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:schemas-NEWSTRING-com:transaction-data-1.69"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <requestMessage xmlns="urn:schemas-NEWSTRING-com:VARIABLESTRING"> 
     <merchantID>TESTID</merchantID> 
     </requestMessage> 
    </soapenv:Body> 
</soapenv:Envelope> 

:文字列VARIABLESTRINGは、すべての入力XMLにして変化するので、それが出力XMLであると私は維持する必要があります

入力XML:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:schemas-OLDSTRING-com:VARIABLESTRING"> 
     <soapenv:Header/> 
     <soapenv:Body> 
      <requestMessage xmlns="urn:schemas-OLDSTRING-com:VARIABLESTRING"> 
      <merchantID>TESTID</merchantID> 
      </requestMessage> 
     </soapenv:Body> 
    </soapenv:Envelope> 

OUTPUTのXML次のXSLを試して名前空間URIを変更することができましたが、 'OLDSTRING'のみを 'NEWSTRING'に置き換え、残りの文字列をそのまま残したいと考えています。

XSLT:これは何をしたい

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|*|text()" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="//*[namespace-uri()='urn:schemas-OLDSTRING-com:VARIABLESTRING']"> 
     <xsl:element name="{local-name()}" namespace="urn:schemas-NEWSTRING-com:VARIABLESTRING" > 
      <xsl:apply-templates select="@*|*|text()" /> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

答えて

0

処理のこの種は、XSLT 2.0に容易であるが、XSLT 1.0でかなりトリッキー:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pTarget" select="'OLDSTRING'"/> 
<xsl:param name="pRepl" select="'NEWSTRING'"/> 

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

<xsl:template match= 
    "*[starts-with(namespace-uri(), 'urn:schemas') 
    or 
    namespace::*[starts-with(., 'urn:schemas')] 
    ]"> 

    <xsl:variable name="vNS" select="namespace-uri()"/> 

    <xsl:variable name="vNewNS"> 
    <xsl:choose> 
     <xsl:when test="not(contains($vNS, $pTarget))"> 
     <xsl:value-of select="$vNS"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="substring-before($vNS, $pTarget)"/> 
     <xsl:value-of select="$pRepl"/> 
     <xsl:value-of select="substring-after($vNS, $pTarget)"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:variable> 

    <xsl:element name="{name()}" namespace="{$vNewNS}"> 
    <xsl:copy-of select= 
    "namespace::* 
     [not(. = $vNS 
      or 
      starts-with(., 'urn:schemas') 
      and 
      contains(., $pTarget) 
      ) 
     ]"/> 

    <xsl:for-each select= 
    "namespace::* 
     [starts-with(., 'urn:schemas') 
     and 
     contains(., $pTarget) 
     ]"> 
    <xsl:variable name="vNewNSUri" select= 
    "concat(substring-before(., $pTarget), 
      $pRepl, 
      substring-after(., $pTarget) 
      ) 
    "/> 

    <xsl:variable name="vPrefix" select="name()"/> 

    <xsl:variable name="vPref"> 
     <xsl:if test="$vPrefix"> 
     <xsl:value-of select="concat($vPrefix, ':')"/> 
     </xsl:if> 
    </xsl:variable> 

    <xsl:variable name="vrtfDoc"> 
     <xsl:element name="{$vPref}dummy" 
        namespace="{$vNewNSUri}"/> 
    </xsl:variable> 

    <xsl:copy-of select= 
    "ext:node-set($vrtfDoc)/*/namespace::*[. = $vNewNSUri]"/> 
    </xsl:for-each> 

    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

この変換が提供されるXML文書に印加された場合:

<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:urn="urn:schemas-OLDSTRING-com:VARIABLESTRING"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <requestMessage xmlns="urn:schemas-OLDSTRING-com:VARIABLESTRING"> 
      <merchantID>TESTID</merchantID> 
     </requestMessage> 
    </soapenv:Body> 
</soapenv:Envelope> 

希望の正しい結果が得られます

<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:urn="urn:schemas-NEWSTRING-com:VARIABLESTRING"> 
    <soapenv:Header /> 
    <soapenv:Body> 
    <requestMessage xmlns="urn:schemas-NEWSTRING-com:VARIABLESTRING"> 
     <merchantID>TESTID</merchantID> 
    </requestMessage> 
    </soapenv:Body> 
</soapenv:Envelope> 
+0

ありがとう。たくさんのことが完璧に働いています – sarma

0

をするのでしょうか?

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|*|text()" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="//*[namespace-uri()='urn:schemas-OLDSTRING-com:VARIABLESTRING']"> 
     <xsl:element name="{local-name()}" namespace="{replace(namespace-uri(), 'OLDSTRING', 'NEWSTRING')}" > 
      <xsl:apply-templates select="@*|*|text()" /> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 
+1

いいえ、XPath 1.0/XSLT 1.0では 'replace()'関数はありません。コードを公開する前に、コードをテストすることをお勧めします。 –

関連する問題