как перебрать только узел первого уровня в xml с x-path? - PullRequest
2 голосов
/ 20 апреля 2011

Мне нужно перебрать файл XML. Корневой узел имеет несколько дочерних элементов, и мне нужно либо скопировать дочерний элемент как есть, либо сделать что-то. Поэтому я работаю над XSLT, чтобы сделать это. Вот пример исходного XML:

<?xml version="1.0" encoding="utf-8"?>
<XDSDocumentEntry id="DOC01">
    <author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST">Author</author>
    <classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
    <confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
</XDSDocumentEntry>

В этом XML мне нужно выбрать узлы author , classCode и confidentialityCodes но я получаю узлы text () с этим кодом:

        <xsl:for-each select="node()"><!--<xsl:copy-of select="."/>-->
            <!--<xsl:value-of select="local-name()"/>-->
            <xsl:choose>
                <xsl:when test="author">
                    do something
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>

Мой результат пока таков:

author<author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST"
       authorInstitution="Some institution"/>
classCode<classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
confidentialityCode<confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
C</confidentialityCode>

Есть подсказка? Thx.


EDIT

Извините, произошла ошибка (я удалил).

На самом деле, почему я использую для каждого , потому что мне нужен документ точно таким, каким он был, за исключением нескольких узлов. В приведенном выше примере окончательный результат должен выглядеть следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<XDSDocumentEntry>
    <author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST"
           authorInstitution="Some institution"/>
    <author>
        <authorInstitution>
            <organizationName>Some institution</organizationName>
        </authorInstitution>
        <authorRole>XDSITEST_DICOM_INSTANCE_PUBLISHER</authorRole>
        <authorPerson>
            <assigningAuthorityName>XDSITEST</assigningAuthorityName>
        </authorPerson>
    </author>
    <classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
    <confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes">
    C</confidentialityCode>
</XDSDocumentEntry>

РЕДАКТИРОВАТЬ 2

Я создал этот шаблон в соответствии с предложением @Martin. Но все же, как мне выбрать имя узла «автор» ??

<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:choose>
            <xsl:when test="local-name()=author">
                    a
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:copy>
</xsl:template>

Ответы [ 3 ]

2 голосов
/ 21 апреля 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="author/node()"/>
    <xsl:template match="author">
        <xsl:call-template name="identity"/>
        <xsl:copy>
            <xsl:apply-templates select="@*" mode="element"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*" mode="element">
        <xsl:element name="{name()}">
            <xsl:apply-templates select="." mode="value"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="author/@authorPerson" mode="value">
        <assigningAuthorityName>
            <xsl:value-of select="."/>
        </assigningAuthorityName>
    </xsl:template>
</xsl:stylesheet>

Вывод:

<XDSDocumentEntry id="DOC01">
    <author authorRole="XDSITEST_DICOM_INSTANCE_PUBLISHER" authorPerson="XDSITEST"></author>
    <author>
        <authorRole>XDSITEST_DICOM_INSTANCE_PUBLISHER</authorRole>
        <authorPerson>
            <assigningAuthorityName>XDSITEST</assigningAuthorityName>
        </authorPerson>
    </author>
    <classCode displayName="Communication" codingScheme="Connect-a-thon classCodes">Communication</classCode>
    <confidentialityCode displayName="Celebrity" codingScheme="Connect-a-thon confidentialityCodes"></confidentialityCode>
</XDSDocumentEntry>
2 голосов
/ 20 апреля 2011

Трудно сказать, что идет не так, не зная контекстного узла вашего for-each. Я бы посоветовал вам забыть о for-each и вместо этого начать писать шаблоны, например

<xsl:template match="XDSDocumentEntry/*">
  <!-- output here what you want to output for child elements of XDSDocumentEntry -->
</xsl:template>

<xsl:template match="XDSDocumentEntry/author">
  <!-- put needed special treatement of author element here -->
</xsl:template>

Если у вас все еще есть проблемы, покажите нам, какой тип вывода вы хотите создать для введенного вами примера ввода, тогда мы можем помочь с правильным кодом XSLT.

[править] Если все, что вам нужно, это копировать узлы, кроме дочерних узлов элемента author, тогда достаточно двух шаблонов:

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="XDSDocumentEntry/author">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
  </xsl:copy>
</xsl:template>
1 голос
/ 21 апреля 2011

Я создал этот шаблон в соответствии с предложением @Martin.Но все же, как мне выбрать имя узла «автор» ??

Ответ :

Вы не выбираете.Вместо этого вы переопределяете шаблон идентификации с более конкретным шаблоном, который точно соответствует узлу (ам) (в вашем случае элемент author, для которого требуется другая обработка, чем просто копирование "как есть")":

<xsl:template match="author">
  <!-- Put your specific code here -->
</xsl:template>

Использование и переопределение правила идентификации является наиболее фундаментальным и мощным шаблоном проектирования XSLT . Подробнее об этом здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...