1

期待どおりにフォーマットされていないXMLを入手することがよくあり、それを自動的に修正するための最良の方法を探しています。残念ながら、解決策は私の頭の上でスケートをすることです。

私は雑誌のコンテンツに取り組んでおり、2つの特定の要素で苦労しています。

There are <subhead> elements, and <body> elements. Even though the subhead element should always be on it's own, sometimes the proofer will accidentally nest it with a <body> node.

<subhead> nodes should be formatted as their own paragraph, wrapped in <p> and <strong> tags.

<body> nodes should just be wrapped in <p> tags.

So I could get either:
<subhead>Dogs</subhead>
<body>Dogs do not like cats.</body>
or
<body><subhead>Dogs</subhead> Dogs do not like cats.</body>

I would like either scenario to output as:
<p><strong>Dogs</strong></p>
<p>Dogs do not like cats.</p>

現在、私のコードは次のようになっています。

<xsl:for-each select="//default:textObject/default:text/*">
<xsl:for-each select="./*">

<xsl:choose>

<xsl:when test="@name='subhead'">
<p><strong>
<xsl:apply-templates select="node()"/>
</strong></p>
</xsl:when>

<xsl:when test="@name='body'">
<p>
<xsl:apply-templates select="node()"/>
</p>
</xsl:when>

...

</xsl:choose>
</xsl:for-each>
</xsl:for-each>

その問題を解決するためにこれをどのように調整できますか?

ありがとうございました。

4

2 に答える 2

2

一般に、予測不可能な入力データ構造に対して XSLT をコーディングしようとすることはお勧めできません。他のネスティング エラーが発生した場合はどうなりますか? 検証のレイヤーを追加することに時間を費やす方がよいでしょう。最も単純な形式では、これはプルーフ担当者が XML を実行する必要がある DTD/スキーマ シートにすぎない場合があります。

それにもかかわらず、あなたの質問に答えるには、これを試してください。各body/subheadペアリングは共通要素 ( item) 内にあると想定しましたが、あなたは言いませんでした。(それ以外の場合、タグ自体がどこにあるのか、どれがどれに関連してsubheadいるかをどのように知ることができますか? それは常に前後の兄弟ですか?)subheadbody

XML

<root>
    <item>
        <subhead>Dogs</subhead>
        <body>Dogs do not like cats.</body>
    </item>
    <item>
        <body><subhead>Dogs</subhead> Dogs do not like cats.</body>
    </item>
</root>

XSL:

<!-- root and static content -->
<xsl:template match="/">
    <xsl:apply-templates select='root/item/body' />
</xsl:template>

<!-- iteration content - subhead/body pairings (matching 'body' nodes) -->
<xsl:template match='body'>
    <p><strong><xsl:value-of select='parent::*/subhead | subhead' /></strong></p>
    <p><xsl:value-of select='text()' /></p>
</xsl:template>

この XMLPlayground セッションで実行できます。

于 2012-06-25T20:21:10.310 に答える
1

この短くてシンプルな完全な変換:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" />
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="(subhead | body/subhead)/text()"/>
  <xsl:text>&#xA;</xsl:text>
  <xsl:apply-templates select="body/text()"/>
 </xsl:template>

 <xsl:template match="subhead/text()">
  <p><strong><xsl:value-of select="."/></strong></p>
 </xsl:template>

 <xsl:template match="body/text()">
  <p><xsl:value-of select="."/></p>
 </xsl:template>
</xsl:stylesheet>

次の XML ドキュメントに適用した場合:

<t>
    <subhead>Dogs</subhead>
    <body>Dogs do not like cats.</body>
</t>

必要な結果が生成されます。

<p><strong>Dogs</strong></p>
<p>Dogs do not like cats.</p>

2 番目のタイプのドキュメントに同じ変換を適用すると、次のようになります。

<t>
    <body><subhead>Dogs</subhead> Dogs do not like cats.</body>
</t>

ここでも同じように、正しい結果が生成されます。

<p><strong>Dogs</strong></p>
<p> Dogs do not like cats.</p>

説明:

特定のテンプレートの結果が出力に表示される順序は、一致したノードの順序ではなく、<xsl:apply-templates>実行のためにテンプレートが選択されるそれぞれの命令の順序に依存します。

注意してください:

ドキュメントの構造が不明な場合は上記のコードを次のように置き換えます。

  <xsl:apply-templates select="(subhead | body/subhead)/text()"/>

と:

  <xsl:apply-templates select="(//subhead | //body/subhead)/text()"/>
于 2012-06-26T02:25:07.723 に答える