XSLT: обработка иерархических данных XML с использованием XSLT - PullRequest
0 голосов
/ 22 марта 2020

У меня есть следующий XML документ. Под каждым узлом есть много подузлов, но меня интересуют только некоторые из них. Моя цель - запустить xslt на нем, чтобы сгенерировать вывод Json, содержащий только те элементы, которые мне интересны.

Подход, который я выбрал, заключается в том, чтобы сначала обработать его как XML (применить все преобразования данных , переименование, вывод только тех элементов, которые меня интересуют ... et c), затем примените еще один 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>

1 Ответ

0 голосов
/ 22 марта 2020

Поскольку использование преобразования идентификаторов с apply-templates имеет «встроенную рекурсию», я не уверен, в чем проблема, вы просто используете его в качестве отправной точки (например, в XSLT 3 с <xsl:mode on-no-match="shallow-copy"/>), а затем добавляете пустой шаблоны, соответствующие элементам, которые вы хотите вырезать, и / или шаблоны, соответствующие тем элементам, которые вы хотите переименовать или преобразовать иначе:

<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

...