XSL转换XML只过滤出元素和属性值?
我需要将以下XML转换为具有相同元素和属性的XML,除了可以本地化的值(基本上是英语短语) 一些元素(XSL转换XML只过滤出元素和属性值?,xml,xslt,localization,xmldiff,Xml,Xslt,Localization,Xmldiff,我需要将以下XML转换为具有相同元素和属性的XML,除了可以本地化的值(基本上是英语短语) 一些元素()和属性是可选的(),我希望能够通用地做到这一点,而无需为每个元素提供模板。可能吗 最终目标是能够将XML的默认版本与本地化版本进行比较,而忽略本地化字符串 例如: <data_schema> <field symbol="ACCOUNT" type="string" name="Account Number"> <validators>
)和属性是可选的(
),我希望能够通用地做到这一点,而无需为每个元素提供模板。可能吗
最终目标是能够将XML的默认版本与本地化版本进行比较,而忽略本地化字符串
例如:
<data_schema>
<field symbol="ACCOUNT" type="string" name="Account Number">
<validators>
<maxlength>6</maxlength>
</validators>
<description>The account number</description>
<example>123456</example>
<default_value></default_value>
</field>
<field symbol="POSTAL_CODE" type="string" name="Postal Code">
<description>Postal Code for account</description>
<example>22022</example>
<footnote>Does not apply to certain accounts</footnote>
<default_value></default_value>
</field>
<field symbol="DISCOUNT" type="string" name="Discount Percentage" display_data_type="percentage">
<description>Descount determined by account</description>
<example>1.5%</example>
<default_value></default_value>
</field>
</data_schema>
6.
账号
123456
账户邮政编码
22022
不适用于某些帐户
按帐户确定的折旧
1.5%
将转换为:
<data_schema>
<field symbol="ACCOUNT" type="string" name="">
<validators>
<maxlength>6</maxlength>
</validators>
<description/>
<example/>
<default_value/>
</field>
<field symbol="POSTAL_CODE" type="string" name="">
<description/>
<example/>
<footnote/>
<default_value/>
</field>
<field symbol="DISCOUNT" type="string" name="" display_data_type="percentage">
<description/>
<example/>
<default_value/>
</field>
</data_schema>
6.
下面是一个例子。应用这样的模板时,应创建树的副本,减去非符号或类型属性的文本区域和属性文本
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:for-each select="@*">
<xsl:choose>
<xsl:when test="name() = 'symbol' or name() = 'type'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="{name()}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
下面是一个例子。应用这样的模板时,应创建树的副本,减去非符号或类型属性的文本区域和属性文本
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:for-each select="@*">
<xsl:choose>
<xsl:when test="name() = 'symbol' or name() = 'type'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="{name()}"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:apply-templates select="*"/>
</xsl:element>
</xsl:template>
这里是另一种方法。这一模式建立在“身份转换”的XSLT设计模式的基础上,基本上只复制所有节点
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
您可以对此进行扩展,以添加其他模板匹配项,以匹配要对其执行特定操作的节点,在您的情况下,就是删除文本。所需的模板取决于转换的确切规则
如果希望从特定元素和属性中删除文本,可以添加以下两个模板,以复制节点,但不复制文本:
<xsl:template match="description|example|footnote|default_value">
<xsl:copy/>
</xsl:template>
<xsl:template match="@name">
<xsl:attribute name="{name()}"/>
</xsl:template>
因此,在这种情况下,元素说明、示例、脚注和默认值的文本连同@name属性一起被删除。所有其他节点将按原样与其文本一起复制
另一方面,如果您有一个特定的元素和属性列表,您希望这些元素和属性保持不变,那么您可以像这样添加模板
<xsl:template match="field/*[not(self::validators)]">
<xsl:copy/>
</xsl:template>
<xsl:template match="@symbol|@type|@display_data_type">
<xsl:copy/>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}"/>
</xsl:template>
因此,对于validators元素,您实际上是说,删除所有不是validators元素的内容。验证程序元素将被身份转换模板复制。对于属性,我展示了一种稍微不同的方法,其中明确列出了要保留的属性,并且您有第二个模板来从所有其他模板中删除文本
这里是本例中的两个完整XSLT
第一个用于从特定节点删除文本
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="description|example|footnote|default_value">
<xsl:copy/>
</xsl:template>
<xsl:template match="@name">
<xsl:attribute name="{name()}"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="field/*[not(self::validators)]">
<xsl:copy/>
</xsl:template>
<xsl:template match="@symbol|@type|@display_data_type">
<xsl:copy/>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}"/>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
第二个用于在特定节点中保留文本
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="description|example|footnote|default_value">
<xsl:copy/>
</xsl:template>
<xsl:template match="@name">
<xsl:attribute name="{name()}"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="field/*[not(self::validators)]">
<xsl:copy/>
</xsl:template>
<xsl:template match="@symbol|@type|@display_data_type">
<xsl:copy/>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}"/>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
对于示例文档,两者应产生相同的输出:
<data_schema>
<field symbol="ACCOUNT" type="string" name="">
<validators>
<maxlength>6</maxlength>
</validators>
<description/>
<example/>
<default_value/>
</field>
<field symbol="POSTAL_CODE" type="string" name="">
<description/>
<example/>
<footnote/>
<default_value/>
</field>
<field symbol="DISCOUNT" type="string" name="" display_data_type="percentage">
<description/>
<example/>
<default_value/>
</field>
</data_schema>
6.
这里是另一种方法。这一模式建立在“身份转换”的XSLT设计模式的基础上,基本上只复制所有节点
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
您可以对此进行扩展,以添加其他模板匹配项,以匹配要对其执行特定操作的节点,在您的情况下,就是删除文本。所需的模板取决于转换的确切规则
如果希望从特定元素和属性中删除文本,可以添加以下两个模板,以复制节点,但不复制文本:
<xsl:template match="description|example|footnote|default_value">
<xsl:copy/>
</xsl:template>
<xsl:template match="@name">
<xsl:attribute name="{name()}"/>
</xsl:template>
因此,在这种情况下,元素说明、示例、脚注和默认值的文本连同@name属性一起被删除。所有其他节点将按原样与其文本一起复制
另一方面,如果您有一个特定的元素和属性列表,您希望这些元素和属性保持不变,那么您可以像这样添加模板
<xsl:template match="field/*[not(self::validators)]">
<xsl:copy/>
</xsl:template>
<xsl:template match="@symbol|@type|@display_data_type">
<xsl:copy/>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}"/>
</xsl:template>
因此,对于validators元素,您实际上是说,删除所有不是validators元素的内容。验证程序元素将被身份转换模板复制。对于属性,我展示了一种稍微不同的方法,其中明确列出了要保留的属性,并且您有第二个模板来从所有其他模板中删除文本
这里是本例中的两个完整XSLT
第一个用于从特定节点删除文本
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="description|example|footnote|default_value">
<xsl:copy/>
</xsl:template>
<xsl:template match="@name">
<xsl:attribute name="{name()}"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="field/*[not(self::validators)]">
<xsl:copy/>
</xsl:template>
<xsl:template match="@symbol|@type|@display_data_type">
<xsl:copy/>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}"/>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
第二个用于在特定节点中保留文本
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="description|example|footnote|default_value">
<xsl:copy/>
</xsl:template>
<xsl:template match="@name">
<xsl:attribute name="{name()}"/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="field/*[not(self::validators)]">
<xsl:copy/>
</xsl:template>
<xsl:template match="@symbol|@type|@display_data_type">
<xsl:copy/>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}"/>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
对于示例文档,两者应产生相同的输出:
<data_schema>
<field symbol="ACCOUNT" type="string" name="">
<validators>
<maxlength>6</maxlength>
</validators>
<description/>
<example/>
<default_value/>
</field>
<field symbol="POSTAL_CODE" type="string" name="">
<description/>
<example/>
<footnote/>
<default_value/>
</field>
<field symbol="DISCOUNT" type="string" name="" display_data_type="percentage">
<description/>
<example/>
<default_value/>
</field>
</data_schema>
6.
正是我所需要的。谢谢错。很明显,无论是答案海报还是OP都没有测试过这个解决方案。肖恩,你错了——这是有效的,对我来说已经足够了。请重试。输出与列出的预期输出不匹配。所以,当你问问题的时候