我需要将XML转换成类似英语句子的内容。例如,以下XML:
<event>
<criteria>
<and>A</and>
<and>B</and>
<and>
<or>
<and>C</and>
<and>D</and>
</or>
<or>E</or>
</and>
</criteria>
</event>
必须变成这样的东西:
To meet the criteria event must have A and B and either C and D or E.
这是一个例子,但“and”和“or”条件可以嵌套得更远。
规则似乎是:
我尝试了几种生成此输出的方法,但都没有成功。一个问题是递归不正确。我见过很多xslt处理的示例,其中一个元素是嵌套的(例如,Item可以由其他Items组成,而其他Items则由其他Items组成,等等),但没有像“and”和“or”这样的两个元素可以是兄弟姐妹和/或相互嵌套的示例。我尝试过使用xsl:模板匹配="and|or"然后测试“and”或“or”,但我要么没有深入到叶子级别,要么事情以错误的顺序出现。
我想知道是否有人可以为我指出正确的方向来处理这样的结构,和/或是否有人可以建议更好的结构来表示“布尔”句子。因为XML尚未最终确定,如果可以使处理更容易,则可以对其进行修改。
注意:我使用的是Saxon 9,可以使用xslt 2.0解决方案。
更多信息:
再次感谢@g-ken-holman。我喜欢建议的自上而下的方法,但我有一些问题。在Ken的例子中,我不确定为什么and/or序列更改为or/and。和/或顺序似乎正确。无论如何,我运行了这个示例,它成功了。然而,我总共收到了5个案例。它适用于前两个具有all和或or的简单情况,以及上述情况下的情况5。但案例3和4不起作用。这是XML和结果。
<event>
<example>3</example>
<criteria>
<or>
<op>A</op>
<op>B</op>
</or>
<and>
<op>C</op>
</and>
</criteria>
</event>
Result: To meet the criteria, event must have either A or B C
Expected: To meet the criteria, event must have either A or B and C
和示例4:
<event>
<example>4</example>
<criteria>
<and>
<op>A</op>
<op>B</op>
</and>
<and>
<or>
<op>C</op>
<op>D</op>
<op>E</op>
</or>
</and>
</criteria>
</event>
结果:要满足标准,事件必须有A和B C或D或E预期:要满足标准,事件必须有A和B,C或D或E
我认为原因是和/或只有在有多个(位置()时才会输出
如果这样会更容易,可以添加一个“任一”元素。
回答说明:
评论部分太长了,所以我在这里添加它。我相信@Ken已经提供了答案,他建议的第二种方法是最好的。
如果我了解处理过程。我们正在匹配文档中的所有节点。我们匹配“事件”,它首先执行,因为它嵌套在其他节点之外。然后,如果遇到一个“and”节点,我们会在“and”上找到一个匹配项,然后(为每个节点)迭代该级别的所有“and”同级。我们不会为第一个节点输出单词“and”,因为测试“position()
我认为这是正确的,但我有一个问题。操作数的文本如何被放入输出?
这个替代答案具有相同的样式表逻辑(唯一的变化是示例编号的说明),但发布是为了解决示例3和4的编辑问题。
您有:
<event>
<example>3</example>
<criteria>
<or>
<op>A</op>
<op>B</op>
</or>
<and>
<op>C</op>
</and>
</criteria>
</event>
我会写下与以下内容相同的内容,使用我的原始逻辑得出您想要的结果:
t:\ftemp>type boolean3.xml
<event>
<example>3</example>
<criteria>
<and>
<or>
<op>A</op>
<op>B</op>
</or>
<op>C</op>
</and>
</criteria>
</event>
t:\ftemp>xslt2 boolean3.xml boolean2.xsl
3 To meet the criteria, event must have either A or B and C
类似地,例如4,您有:
<event>
<example>4</example>
<criteria>
<and>
<op>A</op>
<op>B</op>
</and>
<and>
<or>
<op>C</op>
<op>D</op>
<op>E</op>
</or>
</and>
</criteria>
</event>
我会这样写:
t:\ftemp>type boolean4.xml
<event>
<example>4</example>
<criteria>
<and>
<op>A</op>
<op>B</op>
<or>
<op>C</op>
<op>D</op>
<op>E</op>
</or>
</and>
</criteria>
</event>
t:\ftemp>xslt2 boolean4.xml boolean2.xsl
4 To meet the criteria, event must have A and B and C or D or E
在我的代码中,只有当有两个操作数时,我才使用单词“非此即彼”。。。我想当有两个以上的操作数时,它也可以工作,所以您可以将其添加到处理逻辑中。
以下是为适应示例编号而修改的样式表:
t:\ftemp>type boolean2.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<!--eat white-space-->
<xsl:template match="text()[not(normalize-space())]"/>
<!--start result-->
<xsl:template match="event">
<xsl:value-of select="example"/>
<xsl:text> To meet the criteria, event must have</xsl:text>
<xsl:apply-templates select="criteria"/>
</xsl:template>
<!--handle conjunction-->
<xsl:template match="and">
<xsl:for-each select="*">
<xsl:if test="position()>1"> and</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!--handle alternation-->
<xsl:template match="or">
<xsl:for-each select="*">
<xsl:if test="position()>1"> or</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!--special grammar case for alternation between 2 operands-->
<xsl:template match="or[count(*) = 2]" priority="1">
<xsl:text> either</xsl:text>
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>
所以,这完全取决于您如何编写XML。检查我如何将您所做的重新编写为操作数的工作方式,并询问您是否需要更多说明。
我建议你总是“自上而下”处理数据,而不是试图与兄弟姐妹打交道。
以下是解决方案:
t:\ftemp>type boolean1.xml
<event>
<criteria>
<and>A</and>
<and>B</and>
<and>
<or>
<and>C</and>
<and>D</and>
</or>
<or>E</or>
</and>
</criteria>
</event>
t:\ftemp>call xslt2 boolean1.xml boolean1.xsl
To meet the criteria, event must have A and B and either C and D or E
t:\ftemp>type boolean1.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<!--eat white-space-->
<xsl:template match="text()[not(normalize-space())]"/>
<!--start result-->
<xsl:template match="event">
To meet the criteria, event must have<xsl:apply-templates/>
</xsl:template>
<!--handle conjunction-->
<xsl:template match="*[child::and]">
<xsl:for-each select="child::and">
<xsl:if test="position()>1"> and</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!--handle alternation-->
<xsl:template match="*[child::or]">
<xsl:for-each select="child::or">
<xsl:if test="position()>1"> or</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!--special grammar case for alternation between 2 operands-->
<xsl:template match="*[count(child::or) = 2]" priority="1">
<xsl:text> either</xsl:text>
<xsl:next-match/>
</xsl:template>
<!--don't allow a mixture-->
<xsl:template match="*[child::and and child::or]" priority="2">
<xsl:message terminate="yes">
<xsl:text>A mixture of ands and ors is not allowed.</xsl:text>
</xsl:message>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>rem Done!
至于更改XML的建议,我建议使用一种不允许意外组合的结构,例如“当and和OR都是兄弟时该怎么办”。考虑以下因素:
t:\ftemp>type boolean2.xml
<event>
<criteria>
<and>
<op>A</op>
<op>B</op>
<or>
<and>
<op>C</op>
<op>D</op>
</and>
<op>E</op>
</or>
</and>
</criteria>
</event>
t:\ftemp>call xslt2 boolean2.xml boolean2.xsl
To meet the criteria, event must have A and B and either C and D or E
t:\ftemp>type boolean2.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<!--eat white-space-->
<xsl:template match="text()[not(normalize-space())]"/>
<!--start result-->
<xsl:template match="event">
To meet the criteria, event must have<xsl:apply-templates/>
</xsl:template>
<!--handle conjunction-->
<xsl:template match="and">
<xsl:for-each select="*">
<xsl:if test="position()>1"> and</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!--handle alternation-->
<xsl:template match="or">
<xsl:for-each select="*">
<xsl:if test="position()>1"> or</xsl:if>
<xsl:text> </xsl:text>
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!--special grammar case for alternation between 2 operands-->
<xsl:template match="or[count(*) = 2]" priority="1">
<xsl:text> either</xsl:text>
<xsl:next-match/>
</xsl:template>
</xsl:stylesheet>
t:\ftemp>rem Done!
在第二种方法中,“动作”由元素触发,而不是由子操作数元素触发。我认为这会更直接。
注意,对于英语读者来说,在没有标点符号的情况下深度嵌套and和OR时,可能会遇到一些语法挑战。
XML输入文件: XML输入文件转换为XML输出文件。将XML输入文件的firstName、middleName和lastName标签合并为XML Ouput文件的name标签,将XML输入文件的address1、address2、city、state和pincode标签合并为XML Ouput文件的address标签。 我几乎转换了代码,但我在这里与empId作斗争。我已经在XSLT文件中手动输
我有以下问题。我不是XSLT方面最伟大的专家,我想成功的是将一个XML从赛贝斯转换为以下内容: Sybase的输出: 我希望它的输出标题保持原样,条目部分不同 这是到目前为止我的XSLT(对不起,不太可能) 也许,有人可以帮我实现我想要的。非常感谢你。
问题内容: 我有一个带有三个字段(userId,标题,描述)的索引对象。我想找到标题或说明包含给定关键字的特定用户的所有对象。 我有这样的事情(但这显然是错误的): 如何修改代码以获取具有正确ID和标题或描述中的搜索短语的所有对象? 问题答案: 我认为将是这样的:
问题内容: 我想使用xsl文件转换一些xml并以某种方式输出结果(我使用的是Android Api Level 8)。 我当前的活动看起来像这样,但是转换器保持为空。LogCat引发一个with ,表示xml格式不正确,但是我确定它是正确的。 我在LogCat中发现了一条提示,提示在上述错误消息之前。 我究竟做错了什么? 这是要转换的xml文件(source.xml) 这是对应的xsl(produ
我想使用XSLT将一些XML转换为JSON。XML如下所示: 我希望JSON如下所示: 推荐的方法是什么? 我已经有了一个方法,它看起来不太好,因为它只适用于xslt 1.0(我认为)和文本块。请参阅此处:https://xsltfiddle.liberty-development.net/naZYrpy/1 我更喜欢使用xslt 3.0和xml to json函数的更有效方法,但似乎不可能添加额
本文向大家介绍ASP.NET使用xslt将xml转换成Excel,包括了ASP.NET使用xslt将xml转换成Excel的使用技巧和注意事项,需要的朋友参考一下 序: 最近在给客户做一个管理系统的时候,客户提出要将查询结果导出到Excel。对于还是实习生的我倍感压力,于是找了点资料。网上有个示例,其中方法十分简单。于是照猫画虎,把方法和心得与大家分享。OK,Let`s go 第一步: 创