我有一个大型输入XML,我想为特定客户端缩小它。客户应该只看到与他相关的信息。下面是示例输入。
<?xml version='1.0' encoding='UTF-8' ?>
<reg>
<global>stuff</global>
<profile>
<profile_data>profile stuff 1</profile_data>
<users>
<u><usr_data>usr options 1</usr_data><n>user-1</n></u>
<u><usr_data>usr options 2</usr_data><n>user-2</n></u>
</users>
</profile>
<profile>
<profile_data>profile stuff 2</profile_data>
<users>
<u><usr_data>usr options 3</usr_data><n>user-3</n></u>
<u><usr_data>usr options 4</usr_data><n>user-4</n></u>
</users>
</profile>
</reg>
这需要转换为如下所示的较小 XML:
<?xml version="1.0"?>
<reg>
<global>stuff</global>
<profile>
<profile_data>profile stuff 1</profile_data>
<users>
<u><usr_data>usr options 1</usr_data><n>user-1</n></u>
</users>
</profile>
</reg>
我设法使用串联应用的 2 个 XSLT 转换 (trans1.xml) 完成此操作:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="name"/>
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/reg/profile">
<xsl:if test="./users/*/n=$name">
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
和(trans2.xml):
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="name"/>
<xsl:output method="xml"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/reg/profile/users/*">
<xsl:if test="./n=$name">
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
然后:
xsltproc -param name "'user-1'" trans1.xml input.xml > out1.xml
xsltproc -param name "'user-1'" trans2.xml out1.xml > result.xml
如何将我的 2 个 XSl 样式表转换为 1 个,以在 1 个步骤中执行这 2 个操作。
此转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pName" select="'user-1'"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="profile">
<xsl:if test="users/u/n = $pName">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
<xsl:template match="u">
<xsl:if test="n = $pName">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<reg>
<global>stuff</global>
<profile>
<profile_data>profile stuff 1</profile_data>
<users>
<u>
<usr_data>usr options 1</usr_data>
<n>user-1</n>
</u>
<u>
<usr_data>usr options 2</usr_data>
<n>user-2</n>
</u>
</users>
</profile>
<profile>
<profile_data>profile stuff 2</profile_data>
<users>
<u>
<usr_data>usr options 3</usr_data>
<n>user-3</n>
</u>
<u>
<usr_data>usr options 4</usr_data>
<n>user-4</n>
</u>
</users>
</profile>
</reg>
产生所需的正确结果:
<reg>
<global>stuff</global>
<profile>
<profile_data>profile stuff 1</profile_data>
<users>
<u>
<usr_data>usr options 1</usr_data>
<n>user-1</n>
</u>
</users>
</profile>
</reg>
解释:
正确使用和覆盖标识规则。