XSLT:从转义的XML部分提取节点值

时间:2014-05-07 06:28:05

标签: xml xslt

我有一个XML文档:

<Request>
  <Header>
    <TransactionId>132456789</TransactionId>
    <ExternalId>4544455</ExternalId>
  </Header>
  <Reply>
&lt;S:Envelope&gt;
  &lt;S:Body&gt;
    &lt;ns2:CreateAccountResponse&gt;
      &lt;username&gt;123456789@example.com&lt;/username&gt;
    &lt;/ns2:CreateAccountResponse&gt;
  &lt;/S:Body&gt;
&lt;/S:Envelope&gt;
</Reply>
</Request>

Reply元素中的值也是XML数据。

我需要使用XSL电子表格来提取用户名元素的值。即123456789@abc.net并将其用作另一个元素的值。

目前我正在做以下事情:

<xsl:stylesheet version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:variable name="reply" select="/Request/Reply">
    </xsl:variable>
    <xsl:template match="/">
        <Request>
            <Header>
                <TransactionId>
                    <xsl:value-of select="Request/Header/TransactionId"/>
                </TransactionId>
                <ExternalId><xsl:value-of select="Request/Header/ExternalId"/>
                </ExternalId>
            </Header>

            <Job>
                <CreateUserResponse>
                    <AccountUserName>

                        <xsl:apply-templates select="exsl:node-set($reply)/node()  "/>
                        <xsl:value-of select="$reply//username"/>
                    </AccountUserName>

                </CreateUserResponse>
            </Job>
        </Request>
    </xsl:template>

</xsl:stylesheet>

但我无法从此XSL获取username值。 我需要此值成为<AccountUserName>元素

的值

目前,这是转换后获得的XML。

<?xml version="1.0" encoding="UTF-8"?>
<Request xmlns:ns2="http://example.com/internetdevice" xmlns:S="http://schemas.xmlsoap.org/soap/envelope">
    <Header>
        <TransactionId>132456789</TransactionId>
        <ExternalId>4544455</ExternalId>
    </Header>
    <Job>
        <CreateUserResponse>
            <AccountUserName>&lt;S:Envelope&gt;
                &lt;S:Body&gt;
                &lt;ns2:CreateAccountResponse&gt;
                &lt;username&gt;123456789@example.com&lt;/username&gt;
                &lt;/ns2:CreateAccountResponse&gt;
                &lt;/S:Body&gt;
                &lt;/S:Envelope&gt;</AccountUserName>
        </CreateUserResponse>
    </Job>
</Request>

任何想法/建议将不胜感激。感谢。

2 个答案:

答案 0 :(得分:1)

node-set函数不会像这样解析XML,其目的是将“结果树片段”(带有正文的xsl:variable)转换回您可以导航到的节点集。

相反,您需要为您正在使用的xslt处理器寻找合适的“解析器”扩展函数。 Saxon PE / EE提供saxon:parse,或者如果您使用的是其他处理器,请查看处理器的文档。

答案 1 :(得分:0)

由于您只想从Reply节点内部提取字符串,因此您不必将其转换为节点。您可以搜索&lt;username&gt;字符串,并使用substring函数获取文本。 XPath表达式:

substring-before(substring-after(//Reply,'&lt;username&gt;'),'&lt;/username&gt;')

将在&lt;username&gt;节点中的&lt;/username&gt;Reply之间返回字符串。

你可以写一个更简单的XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:template match="Request">
        <xsl:copy>
            <xsl:copy-of select="Header" />
            <Job>
                <CreateUserResponse>
                    <AccountUserName>
                        <xsl:value-of select="substring-before(substring-after(Reply,'&lt;username&gt;'),'&lt;/username&gt;')"/>
                    </AccountUserName>
                </CreateUserResponse>
            </Job>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这将生成包含username

的以下结果XML
<Request>
   <Header>
        <TransactionId>132456789</TransactionId>
        <ExternalId>4544455</ExternalId>
    </Header>
   <Job>
      <CreateUserResponse>
         <AccountUserName>123456789@example.com</AccountUserName>
      </CreateUserResponse>
   </Job>
</Request>

如果需要操作节点中的数据,可以使用XSLT 2.0替换尖括号并重新处理结果。请参阅 this question 的答案,其中包含一个示例。