XSLT:使用XSLT处理分层XML数据



我有下面的XML文档。每个节点下都有许多子节点,但我只对其中的几个感兴趣。我的目标是在上面运行xslt以生成Json输出,该输出只包含我感兴趣的元素。

我采用的方法是先将其处理为XML(应用所有数据转换、重命名、只输出我感兴趣的元素……等等(,然后应用另一个xslt将其转换为Json(我在网上找到了一些现成的xslt可以做到这一点(。

我现在的问题主要是递归部分,我无法纠正,我尝试了每个/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的身份转换具有"内置递归"功能,我不确定问题出在哪里,您只需将其作为起点(例如,在带有<xsl:mode on-no-match="shallow-copy"/>的XSLT3中(,然后添加与要剥离的元素相匹配的空模板和/或与要重命名或转换的元素匹配的模板:

<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>

https://xsltfiddle.liberty-development.net/6pS26my

最新更新