XSLT:使用 XSLT 处理分层 XML 数据
XSLT: Processing hierarchical XML data using XSLT
我有以下 XML 文档。每个节点下都有很多子节点,但我只对其中的几个感兴趣。
我的目标是 运行 xslt 在它上面生成一个 Json 输出只包含我感兴趣的元素。
我采用的方法是首先将其处理为 XML(应用所有数据转换、重命名、仅输出我感兴趣的元素...等)然后应用另一个 xslt 将其转换为 Json(我在网上找到了一些现成的 xslt 可以做到这一点)。
我现在的问题主要在递归部分,我做不对,我试过了for-each/apply-templates/call-template,但我还是很难做。
<MainDoc>
<MetaData>
<Name>MainDoc Name</Name>
<Date>MainDoc Date</Date> <!--not interested in this element-->
</MetaData>
<ContentList>
<Content/>
<Content/>
<Content><!--Want to process last content only-->
<BuildList>
<Build>
<Steps>
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>myTitle1</Title>
<Details>myDetails1</Details>
<Date>Step Date</Date> <!--not interested in this element-->
</StepContent>
</StepContentParent>
<Steps><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>myTitle1.1</Title>
<Details>myDetails1.1</Details>
</StepContent>
</StepContentParent>
<Steps/><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc><!-- Same as Root (recursion ) -->
<MetaData>
<Name>Sub Doc Name</Name>
</MetaData>
<ContentList>
<Content/>
<Content/>
<Content><!--Want to process last content only-->
<BuildList>
<Build>
<Steps>
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>Sub Doc myTitle1</Title>
<Details>Sub Doc myDetails1</Details>
</StepContent>
</StepContentParent>
<Steps><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>Sub Doc myTitle1.1</Title>
<Details>Sub Doc myDetails1.1</Details>
</StepContent>
</StepContentParent>
<Steps/><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc/><!-- Same as Root (recursion ) -->
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
<step/>
<step/>
</Steps>
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc/><!-- Same as Root (recursion ) -->
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
</Steps>
</Build>
</BuildList>
</Content>
</ContentList>
</MainDoc>
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
<step/>
<step/>
</Steps>
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc/><!-- Same as Root (recursion ) -->
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
<Step>
<StepContentParent>
<StepContent>
<Title>myTitle2</Title>
<Details>myDetails2</Details>
</StepContent>
</StepContentParent>
<Steps><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>myTitle2.1</Title>
<Details>myDetails2.1</Details>
</StepContent>
</StepContentParent>
<Steps/><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc/><!-- Same as Root (recursion ) -->
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
<step/>
<step/>
</Steps>
</Step>
<step/>
<step/>
</Steps>
</Build>
</BuildList>
</Content>
</ContentList>
</MainDoc>
因为使用带有 apply-templates
的身份转换有 "recursion built-in" 我不确定问题出在哪里,您只是将它用作起点(例如在 XSLT 3 中带有 <xsl:mode on-no-match="shallow-copy"/>
),然后添加与要去除的元素相匹配的空模板 and/or 与要重命名或转换的元素相匹配的模板:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="MainDoc/MetaData/Date"/>
<xsl:template match="StepContentParent/StepContent/Date"/>
<xsl:template match="ContentList/Content[not(position() = last())]"/>
</xsl:stylesheet>
我有以下 XML 文档。每个节点下都有很多子节点,但我只对其中的几个感兴趣。 我的目标是 运行 xslt 在它上面生成一个 Json 输出只包含我感兴趣的元素。
我采用的方法是首先将其处理为 XML(应用所有数据转换、重命名、仅输出我感兴趣的元素...等)然后应用另一个 xslt 将其转换为 Json(我在网上找到了一些现成的 xslt 可以做到这一点)。
我现在的问题主要在递归部分,我做不对,我试过了for-each/apply-templates/call-template,但我还是很难做。
<MainDoc>
<MetaData>
<Name>MainDoc Name</Name>
<Date>MainDoc Date</Date> <!--not interested in this element-->
</MetaData>
<ContentList>
<Content/>
<Content/>
<Content><!--Want to process last content only-->
<BuildList>
<Build>
<Steps>
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>myTitle1</Title>
<Details>myDetails1</Details>
<Date>Step Date</Date> <!--not interested in this element-->
</StepContent>
</StepContentParent>
<Steps><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>myTitle1.1</Title>
<Details>myDetails1.1</Details>
</StepContent>
</StepContentParent>
<Steps/><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc><!-- Same as Root (recursion ) -->
<MetaData>
<Name>Sub Doc Name</Name>
</MetaData>
<ContentList>
<Content/>
<Content/>
<Content><!--Want to process last content only-->
<BuildList>
<Build>
<Steps>
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>Sub Doc myTitle1</Title>
<Details>Sub Doc myDetails1</Details>
</StepContent>
</StepContentParent>
<Steps><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>Sub Doc myTitle1.1</Title>
<Details>Sub Doc myDetails1.1</Details>
</StepContent>
</StepContentParent>
<Steps/><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc/><!-- Same as Root (recursion ) -->
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
<step/>
<step/>
</Steps>
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc/><!-- Same as Root (recursion ) -->
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
</Steps>
</Build>
</BuildList>
</Content>
</ContentList>
</MainDoc>
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
<step/>
<step/>
</Steps>
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc/><!-- Same as Root (recursion ) -->
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
<Step>
<StepContentParent>
<StepContent>
<Title>myTitle2</Title>
<Details>myDetails2</Details>
</StepContent>
</StepContentParent>
<Steps><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<Step><!--want to process all of them-->
<StepContentParent>
<StepContent>
<Title>myTitle2.1</Title>
<Details>myDetails2.1</Details>
</StepContent>
</StepContentParent>
<Steps/><!--Could be empty or could be the same as the previous Steps (recursion ) -->
<SubDoc><!-- could be empty -->
<SubDocInstance>
<DocInstance>
<MainDoc/><!-- Same as Root (recursion ) -->
</DocInstance>
</SubDocInstance>
</SubDoc>
</Step>
<step/>
<step/>
</Steps>
</Step>
<step/>
<step/>
</Steps>
</Build>
</BuildList>
</Content>
</ContentList>
</MainDoc>
因为使用带有 apply-templates
的身份转换有 "recursion built-in" 我不确定问题出在哪里,您只是将它用作起点(例如在 XSLT 3 中带有 <xsl:mode on-no-match="shallow-copy"/>
),然后添加与要去除的元素相匹配的空模板 and/or 与要重命名或转换的元素相匹配的模板:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="MainDoc/MetaData/Date"/>
<xsl:template match="StepContentParent/StepContent/Date"/>
<xsl:template match="ContentList/Content[not(position() = last())]"/>
</xsl:stylesheet>