我有一个如下的 xml 文件,我想将其转换为纯文本文件。
<?xml version="1.0" encoding="UTF-8"?>
<abc xmlns="ddn:cns-org:v5">
<section>
<title>PREORDER</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>preorder.</content>
<content></content>
</paragraph>
<paragraph>
<content>preorder description.</content>
<content>preorder detail goes here.</content>
</paragraph>
</text>
</section>
<section>
<title>POSTORDER</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>postorder.</content>
</paragraph>
</text>
</section>
</abc>
我想要这样的输出:
PREORDER
(ignore the line of <code .../>
pre-order.
(Note: if there is no content - <content></content>, don't record anything)
preorder description.
preorder detail goes here.
POSTORDER
post-order.
我试图使用 xsl 转换,但我不太了解路径/节点。我得到了类似以下的东西,显然它没有用。请帮忙。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
abc xmlns="ddn:cns-org:v5">
<xsl:output method="text" omit-xml-declaration="yes"/>
<!-- ***********************************************************
Call template process section
************************************************************-->
<xsl:template match="/">
<!-- <xsl:for-each select="abc"> -->
<xsl:for-each select="section">
<xsl:call-template name="process_section"> </xsl:call-template>
</xsl:for-each>
<!-- </xsl:for-each> -->
</xsl:template>
<xsl:template name="process_section">
<!-- Choose : Section or Subsection -->
<xsl:choose>
<!-- ***********************************************************************************
(if section:
*check if not empty title
* Bring to upper case
* check if already one colon, don't put any more
* put newline
******************************************************************************************-->
<xsl:when test=" local-name(.)='abc' ">
<xsl:if test="not(string-length(normalize-space(./section/title))=0)">
<xsl:variable name="title" select="string(./section/title)"/>
<xsl:value-of
select="translate($title, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<xsl:if test="not( substring($title, string-length($title),1)=':' )">
<xsl:text>:</xsl:text>
</xsl:if>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:when>
...
谢谢,戴夫
现在我需要将 xml 文件转换为格式正确的文本文件。给定源 xml 文件为:
<?xml version="1.0" encoding="UTF-8"?>
<abc xmlns="ddn:cns-org:v5">
<section>
<title>PREOPERATIVE DIAGNOSIS </title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>__ c</content>
<content>ataract.</content>
</paragraph>
</text>
</section>
<section>
<title>POSTOPERATIVE DIAGNOSIS</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>__ c</content>
<content>ataract.</content>
</paragraph>
</text>
</section>
<section>
<title>OPERATION</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>Pars plana vitrectomy
and epiretinal membrane removal. Phacoemulsification with posterior
chamber lens implant __(Control #</content>
<content>__</content>
<content>) </content>
</paragraph>
</text>
</section>
<section>
<title>SURGEON</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>Dr. J. R. xxx
</content>
</paragraph>
</text>
</section>
<section>
<title>DOCTORS IN ATTENDANCE</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph />
</text>
</section>
<section>
<title>ANESTHETIST</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph />
</text>
</section>
<section>
<title>ANESTHESIA</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph />
</text>
</section>
<section>
<title>CLINICAL NOTE</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph />
</text>
</section>
<section>
<title>OPERATIVE PROCEDURE</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>Topical sterilization,
anesthesia and dilatation were carried out in the Day Surgery Unit
before the patient was brought to the Operating room. </content>
</paragraph>
<paragraph />
<paragraph>
<content>The patient was
prepared with Proviodine. The patient was then draped. Special
attention was directed to the eyelids/lashes, prepping and draping.
A speculum was inserted into the fornices of the</content>
<content> __</content>
<content> eye. Subconjunctival
Xylocaine was given. A small conjunctival peritomy was made in the
area of the subconjunctival injection. Three cc of 2% Xylocaine and
0.75% Marcaine were injected into the sub-Tenon's space through the
peritomy. </content>
</paragraph>
<paragraph />
<paragraph>
<content>A paracentesis was
performed superiorly and inferiorly. Intraocular nonpreserved
Xylocaine was used. A viscoelastic was injected into the anterior
chamber. The eye was entered with a 3 mm keratome. The anterior
capsulectomy was done under a viscoelastic. Hydrodissection and
delineation of the nucleus was carried out. The
phaco-emulsification was initiated. The phacoemulsification time
was </content>
<content>__</content>
<content> seconds. At the
completion of the phacoemulsification, the cortical material was
irrigated and aspirated from the eye. The posterior capsule was
polished. The intraocular lens was inserted under a viscoelastic.
The intraocular lens power was __ diopters. </content>
</paragraph>
<paragraph />
<paragraph>
<content>The lens was the dialed
into position with the lens pick. Irrigation and aspiration of the
viscoelastic was then carried out. The wound was tested to ensure
that there was no wound leak. </content>
</paragraph>
<paragraph />
<paragraph>
<content>Additional periglobal
anesthesia of 2% Xylocaine and 0.75% Marcaine was injected into the
sub-Tenon's space through the peritomy. </content>
</paragraph>
<paragraph />
<paragraph>
<content>The 25-gauge cannulas
were then placed inferotemporal, supratemporal and supranasally. In
the infratemporal cannula an infusion placed. </content>
</paragraph>
<paragraph />
<paragraph>
<content>A vitrectomy was then
carried out. </content>
</paragraph>
<paragraph />
<paragraph>
<content>__ (Dr. xxx will
refer to this area as an "open paragraph</content>
<content>"</content>
<content>- DELETE THIS
INFORMATION</content>
<content>)</content>
</paragraph>
<paragraph />
<paragraph>
<content>At the completion of
the vitrectomy, the peripheral retina was reinspected to ensure
there was no untreated peripheral retinal tears or detachment. The
cannulas were removed. The scleral wounds inspected and if a wound
leak was identified, then this was closed with 9-0 Vicryl suture.
Otherwise interrupted 9-0 Vicryl sutures were placed.
Subconjunctival Decadron and cefuroxime were given. </content>
</paragraph>
<paragraph />
<paragraph>
<content>A patch and shield
applied. </content>
</paragraph>
<paragraph />
<paragraph>
<content>The patient left the
Operating Room in satisfactory condition. </content>
</paragraph>
</text>
</section>
<section>
<title>ADDENDUM</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph />
</text>
</section>
<section>
<title>POSTOPERATIVE TOPICAL EYE DROPS</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>1. Maxidex.</content>
</paragraph>
<paragraph>
<content>2. Nevanac.</content>
</paragraph>
<paragraph>
<content>3. Vigamox.</content>
</paragraph>
</text>
</section>
<section>
<title>POSTOPERATIVE FOLLOWUP</title>
<code code="0" cs="12.222" csn="CSN" />
<text>
<paragraph>
<content>__</content>
</paragraph>
</text>
</section>
</abc>
我希望得到如下输出。
PREOPERATIVE DIAGNOSIS:
__ cataract.
POSTOPERATIVE DIAGNOSIS:
__ cataract.
OPERATION:
Pars plana vitrectomy and epiretinal membrane removal. Phacoemulsification with posterior chamber lens implant __(Control #__)
SURGEON:
Dr. J. R. xxx
DOCTORS IN ATTENDANCE:
ANESTHETIST:
ANESTHESIA:
CLINICAL NOTE:
OPERATIVE PROCEDURE:
Topical sterilization, anesthesia and dilatation were carried out in the Day Surgery Unit before the patient was brought to the Operating room.
The patient was prepared with Proviodine. The patient was then draped. Special attention was directed to the eyelids/lashes, prepping and draping. A speculum was inserted into the fornices of the __ eye. Subconjunctival Xylocaine was given. A small conjunctival peritomy was made in the area of the subconjunctival injection. Three cc of 2% Xylocaine and 0.75% Marcaine were injected into the sub-Tenon's space through the peritomy.
A paracentesis was performed superiorly and inferiorly. Intraocular nonpreserved Xylocaine was used. A viscoelastic was injected into the anterior chamber. The eye was entered with a 3 mm keratome. The anterior capsulectomy was done under a viscoelastic. Hydrodissection and delineation of the nucleus was carried out. The phaco-emulsification was initiated. The phacoemulsification time was __ seconds. At the completion of the phacoemulsification, the cortical material was irrigated and aspirated from the eye. The posterior capsule was polished. The intraocular lens was inserted under a viscoelastic. The intraocular lens power was __ diopters.
The lens was the dialed into position with the lens pick. Irrigation and aspiration of the viscoelastic was then carried out. The wound was tested to ensure that there was no wound leak.
Additional periglobal anesthesia of 2% Xylocaine and 0.75% Marcaine was injected into the sub-Tenon's space through the peritomy.
The 25-gauge cannulas were then placed inferotemporal, supratemporal and supranasally. In the infratemporal cannula an infusion placed.
A vitrectomy was then carried out.
__ (Dr. xxx will refer to this area as an "open paragraph"- DELETE THIS INFORMATION)
At the completion of the vitrectomy, the peripheral retina was reinspected to ensure there was no untreated peripheral retinal tears or detachment. The cannulas were removed. The scleral wounds inspected and if a wound leak was identified, then this was closed with 9-0 Vicryl suture. Otherwise interrupted 9-0 Vicryl sutures were placed. Subconjunctival Decadron and cefuroxime were given.
A patch and shield applied.
The patient left the Operating Room in satisfactory condition.
ADDENDUM:
POSTOPERATIVE TOPICAL EYE DROPS:
1. Maxidex.
2. Nevanac.
3. Vigamox.
POSTOPERATIVE FOLLOWUP:
__
变换规则如下:
部分应由一个新的空行分隔。
部分标题应全部为大写字母,后跟冒号 (:),并应进行修剪。
每个标题都应该用新的空行分隔(之前和之后)。
每个段落都应该用新的空行分隔(之前和之后)。
一个段落内的所有内容应合并为单行。
我在项目中发现了一些我想重用的类似代码。但是,我很难弄清楚 xPath func/variables。我真的很想将它与 Mads 提供的代码结合起来。但我失败了。
这是我打算运行的代码。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="ddn:cns-org:v5">
<xsl:output method="text" omit-xml-declaration="yes"/>
<!-- ***********************************************************
Call template process section
************************************************************-->
<xsl:template match="/">
<xsl:for-each select="d:abc/d:section"> <!-- Is it OK?-->
<xsl:call-template name="process_section"> </xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="process_section">
<xsl:if test="not(string-length(normalize-space(./section/title))=0)">
<xsl:variable name="title" select="string(./section/title)"/>
<xsl:value-of
select="translate($title, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<xsl:if test="not( substring($title, string-length($title),1)=':' )">
<xsl:text>:</xsl:text>
</xsl:if>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:if test="not(string-length(normalize-space(./section/title))=0)">
<xsl:variable name="title" select="string(./section/title)"/>
<xsl:call-template name="TitleCase">
<!-- <xsl:with-param name="text" select="./section/title"/> -->
<xsl:with-param name="title" select="$title"/>
<xsl:with-param name="start" select="true()"/>
</xsl:call-template>
<xsl:if test="not( substring($title, string-length($title),1)=':' )">
<xsl:text>:</xsl:text>
</xsl:if>
<xsl:text>
</xsl:text>
</xsl:if>
<!-- *****************************************************************************************
Start processing Text .Paragraph/list under section/text.
****************************************************************************************************-->
<xsl:for-each select="./section/text/node()">
<xsl:choose>
<!-- ************************************************************************************
if a node under text is a paragraph
*Replace single ':' (no caret / no digit in front) with caret followed by colon '^:'
*Also, do not put newline if there is nothing withing paragraph
*(level section/text/paragraph or node())
******************************************************************************************-->
<xsl:when test="local-name()='paragraph'">
<xsl:for-each
select="./content[not(@styleCode='hidden' or @styleCode='bookmark')]">
<xsl:choose>
<xsl:when test="contains(., ':')">
<xsl:call-template name="replaceColon">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:if
test="(count(./content[not(@styleCode='hidden' or @styleCode='bookmark')]) > 0) or (count(./content)=0)">
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:when>
<!-- otherwise it has to be list -->
<xsl:when test="local-name()='list'">
<xsl:call-template name="listProcessing"> </xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<!-- ********************************************************************
Done w/ Text (paragraph/list) done. Go back to (level component)
**************************************************************************-->
<xsl:if
test="string-length(normalize-space(.//content[not(@styleCode='hidden' or @styleCode='bookmark')]/text())) > 0">
<xsl:text>
</xsl:text>
</xsl:if>
<!-- Subsection. (Level component) -->
<xsl:for-each select="./section/component">
<xsl:if test="not(./section/code/@code='9001')">
<xsl:call-template name="process_section"/>
</xsl:if>
</xsl:for-each>
<!-- ******************************************
end of processing component
*******************************************-->
</xsl:template>
<xsl:template name="replaceColon">
<xsl:param name="text"/>
<xsl:variable name="before" select="substring-before($text,':')"/>
<xsl:variable name="after" select="substring-after($text,':')"/>
<xsl:choose>
<xsl:when test="contains($before, ':')">
<xsl:call-template name="replaceColon">
<xsl:with-param name="text" select="$before"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when
test="string (number(substring($before,string-length($before),1))) != 'NaN'
or string (substring($before,string-length($before),1)) = '^'">
<xsl:value-of select="$before"/>
<xsl:text>:</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$before"/>
<xsl:text>^:</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="contains($after, ':')">
<xsl:call-template name="replaceColon">
<xsl:with-param name="text" select="$after"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$after"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- *********************************************************
Begining listProcessing. (Level ./section/text/list)
*********************************************************** -->
<xsl:template name="listProcessing">
<!-- ***iterate each item under list (Level ./section/text/list/item)********* -->
<xsl:for-each select="./item">
<xsl:value-of select="position()"/>
<xsl:value-of select="'. '"/>
<!-- Checking node under item. (Level ./section/text/list/item/node()) -->
<xsl:for-each select="./node()">
<xsl:choose>
<!-- ******************************
Make sure the paragraph has content, otherwise don't print it or the newline. (CP-5076)
******************************** -->
<xsl:when test="local-name(.)='paragraph' and string-length(.)>0">
<!-- print paragraph content -->
<xsl:for-each
select="./content[not(@styleCode='hidden' or @styleCode='bookmark')]">
<xsl:choose>
<xsl:when test="contains(., ':')">
<xsl:call-template name="replaceColon">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:when>
<!-- ******* otherwise it has to be list with a list *********** -->
<xsl:when test="local-name(.)='list'">
<!-- ******call listProcessing recursively****** -->
<xsl:call-template name="listProcessing"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<!-- node -->
</xsl:for-each>
<!-- item -->
<!-- *********** End listProcessing******** -->
</xsl:template>
<!-- *****************************************************
******** Title Case**************** *********************
****************************************************-->
<xsl:template name="TitleCase">
<xsl:param name="title"/>
<xsl:param name="start"/>
<xsl:choose>
<xsl:when test="$start=true()">
<xsl:choose>
<xsl:when test="contains(substring($title,1,1),'[')">
<!-- found start bracket -->
<xsl:variable name="romanNumneral"
select="substring-before(substring-after($title,'['),']')"/>
<xsl:value-of select="$romanNumneral"/>
<xsl:variable name="title2"
select="substring($title,string-length($romanNumneral)+3)"/>
<xsl:if test="string-length($title2) > 0">
<!-- this is end condition for recursive call -->
<xsl:call-template name="TitleCase">
<xsl:with-param name="title" select="$title2"/>
<xsl:with-param name="start" select="true()"/>
<!-- "[IV] axis" in this case it should become "IV Axis", so call with true -->
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<!-- title case me -->
<xsl:value-of
select="translate(substring($title,1,1),'abcdefghijklmnopqrstuvwxyz:','ABCDEFGHIJKLMNOPQRSTUVWXYZ:')"/>
<xsl:variable name="title2" select="substring($title,2)"/>
<xsl:if test="string-length($title2) > 0">
<xsl:call-template name="TitleCase">
<xsl:with-param name="title" select="$title2"/>
<xsl:with-param name="start" select="false()"/>
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- start test ends -->
<xsl:when test="contains(substring($title,1,1),'[')">
<!-- roman test -->
<xsl:variable name="romanNumneral"
select="substring-before(substring-after($title,'['),']')"/>
<xsl:value-of select="$romanNumneral"/>
<xsl:variable name="title2"
select="substring($title,string-length($romanNumneral)+3)"/>
<xsl:if test="string-length($title2) > 0">
<xsl:call-template name="TitleCase">
<xsl:with-param name="title" select="$title2"/>
<xsl:with-param name="start" select="false()"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<!-- end Roman test -->
<xsl:otherwise>
<!-- small-test case start -->
<xsl:value-of
select="translate(string(substring($title,1,1)), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ:', 'abcdefghijklmnopqrstuvwxyz:')"/>
<xsl:variable name="title2" select="substring($title,2)"/>
<xsl:if test="string-length($title2) > 0">
<xsl:choose>
<xsl:when test="not(contains($title2, ']'))">
<xsl:value-of
select="translate($title2, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ:', 'abcdefghijklmnopqrstuvwxyz:')"/>
<!-- <xsl:value-of select="$title2"/> -->
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="TitleCase">
<xsl:with-param name="title" select="$title2"/>
<xsl:with-param name="start" select="false()"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:otherwise>
<!-- small-case test ends here -->
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
请帮忙。
谢谢,戴夫