如何使用 XSL 对 XML 中特定元素的所有子元素进行大于和小于号转义



我是XML和XSL的新手。我要求编写一个 XSL 脚本,用转义字符串替换某些子元素的大号 (>) 和小于 (<) 符号。我需要对"startupXml"元素中的子元素执行替换(请参阅下面的代码)

<?xml version="1.0" encoding="utf-8" ?>
<s:Envelope  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <Startup2 xmlns="http://keyfax.touch-base.com/">
            <startupXml>
                <KeyfaxData>
                    <Startup>
                        <Config>Test</Config>
                        <Mode>RD</Mode>
                        <UserName>JBLOG</UserName>
                        <PropertyType>P</PropertyType>
                        <PropertyID>L0000</PropertyID>
                        <ReferenceID>12345</ReferenceID>
                        <Property>
                            <ContactHistory/>
                        </Property>
                    </Startup>
                </KeyfaxData>
            </startupXml>
        </Startup2>
    </s:Body>
</s:Envelope>

结果应如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<s:Envelope  xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <Startup2 xmlns="http://keyfax.touch-base.com/">
            <startupXml>
                &lt;KeyfaxData&gt;
                    &lt;Startup&gt;
                        &lt;Config&gt;Test&lt;/Config&gt;
                        &lt;Mode&gt;RD&lt;/Mode&gt;
                        &lt;UserName&gt;JBLOG&lt;/UserName&gt;
                        &lt;PropertyType&gt;P&lt;/PropertyType&gt;
                        &lt;PropertyID&gt;L0000&lt;/PropertyID&gt;
                        &lt;ReferenceID&gt;12345&lt;/ReferenceID&gt;
                        &lt;Property&gt;
                            &lt;ContactHistory/&gt;
                        &lt;/Property&gt;
                    &gt;/Startup&lt;
                &gt;/KeyfaxData&lt;
            </startupXml>
        </Startup2>
    </s:Body>
</s:Envelope>

我尝试了一些 xsl 脚本来查找和替换,但由于我是 XML 和 XSL 的新手,结果并不成功。有人可以指出我正确的方向吗?

提前谢谢。

在这种一般情况下(转义特定输入元素的所有后代元素),您可以使用

XSLT 样式表(在线)

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
    xmlns:kf="http://keyfax.touch-base.com/">
    <xsl:output method="xml" omit-xml-declaration="no" encoding="UTF-8" indent="yes" />
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="kf:startupXml//*">
        <xsl:value-of select="concat('&lt;',name(),'&gt;')"/>
            <xsl:apply-templates/>
        <xsl:value-of select="concat('&lt;/',name(),'&gt;')"/>
    </xsl:template>
</xsl:transform>

XML 输出

您的预期输出会立即关闭 ContactHistory 元素:&lt;Contact History/&gt; ,但这需要额外的逻辑。

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <Startup2 xmlns="http://keyfax.touch-base.com/">
            <startupXml>
                &lt;KeyfaxData&gt;
                    &lt;Startup&gt;
                        &lt;Config&gt;Test&lt;/Config&gt;
                        &lt;Mode&gt;RD&lt;/Mode&gt;
                        &lt;UserName&gt;JBLOG&lt;/UserName&gt;
                        &lt;PropertyType&gt;P&lt;/PropertyType&gt;
                        &lt;PropertyID&gt;L0000&lt;/PropertyID&gt;
                        &lt;ReferenceID&gt;12345&lt;/ReferenceID&gt;
                        &lt;Property&gt;
                            &lt;ContactHistory&gt;&lt;/ContactHistory&gt;
                        &lt;/Property&gt;
                    &lt;/Startup&gt;
                &lt;/KeyfaxData&gt;
            </startupXml>
        </Startup2>
    </s:Body>
</s:Envelope>

您需要记住的主要事情是 XSLT 看不到标记,它看到通过解析标记形成的节点树。所以你需要一个这样的模板规则:

<xsl:template match="*" mode="escape-markup">
  <xsl:text>&lt;</xsl:text>
  <xsl:value-of select="name()"/>
  <xsl:text>&gt;</xsl:text>
  <xsl:apply-templates mode="#current"/>
  <xsl:text>&lt;/</xsl:text>
  <xsl:value-of select="name()"/>
  <xsl:text>&gt;</xsl:text>
</xsl:template>

然后,当您点击相关元素时调用它:

<xsl:template match="startUpXml">
  <xsl:apply-templates mode="escape-markup"/>
</xsl:template>

如果您必须处理属性和命名空间,它会变得有点复杂。

最新更新