- PR -

VBでDOMを使って、DTDの属性リスト宣言からデフォルト値を取得するには

投稿者投稿内容
きょうこ
会議室デビュー日: 2001/11/25
投稿数: 4
投稿日時: 2001-11-25 22:55
VBでDOMを使って、dtdの属性リスト宣言を参照し
ある要素のある属性のデフォルト値を取得したいのですが
どのようにすれば可能でしょうか。
また不可能な場合は、DOMを使用せずに他の方法で
そういったことはできないでしょうか。
よろしくご教示ください。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2001-11-26 15:52
はじめまして、
"C:\Program Files\Microsoft XML Parser SDK\Docs\xmlsdk30.chm"の
普通の書き方で大丈夫なはずですが。
MSXML3.dll(+SP2) のインストールができているか確認しましょう。
------------------ DefaAtt.xml IE表示でも属性は見えます。
<?xml version="1.0"?>
<!DOCTYPE TOP [
<!ELEMENT TOP (#PCDATA)>
<!ATTLIST TOP DEFAU CDATA "attdefault">
]>
<TOP>kkkkkkk</TOP>
------------------ defa.htm
<html><head><title>defa</title></head>
<body><script>
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
xmlDoc.async = false;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.load("DefaAtt.xml");
alert(xmlDoc.xml);
//
var objNodeList = xmlDoc.getElementsByTagName("TOP");
var Elm=objNodeList.item(0);
alert(Elm.xml);
var namedNodeMap = Elm.attributes;
alert( namedNodeMap.length);
var defau = namedNodeMap.getNamedItem("DEFAU");
alert(defau.value);
</script></body></html>
----------------
resolveExternals* プロパティ
Indicates whether external definitions (resolvable namespaces,
DTD external subsets,
and external entity references) are to be resolved
at parse time, independent of validation. Read/write
も必要であれば付けますが。
きょうこ
会議室デビュー日: 2001/11/25
投稿数: 4
投稿日時: 2001-11-26 21:45
きょうこです。
さっそくご回答いただきありがとうございます。
最初の質問の書き方が悪かったため、お聞きしたかった事が
明確に伝わらなかったようで、申し訳ありません。

もう一度、補足させていただくと、プログラミング言語はVisualBasicで
やりたいことは、DBのテーブル(MsAccess)をもとに、
XMLファイルを生成するのですが、そのとき
DTDファイルを参照して、要素名と属性名を元に
<!ATTLIST 要素名 属性名 データ型 #FIXED デフォルト値>
のデフォルト値を取得し、その値を属性値としてXMLファイルに
書き出したいのです。
その中で、DTD定義の中の属性のデフォルト値を取り出す方法が
どうしても解らなくて、投稿しました。

MMXさんの例でいうと、
<!ATTLIST TOP DEFAU CDATA "attdefault"> の"attdefault"を取得し
<TOP DEFAU="attdefault">kkkkkkk</TOP> とファイルに出力することになります。

DocumentTypeオブジェクトから、たどっていって参照できないか思ったのですが、
エンティティ宣言や記法宣言の内容は参照できても
属性リスト宣言については、やはり方法が解りませんでした。
もしこのような方法をご存知でしたら、お教えいただけませんでしょうか。
よろしくお願いいたします。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2001-11-26 22:11
DTDの内容を扱うAPIはMSXMLのDOMには無いので、外でテキスト操作に
なると思います。DTDのテキストを正規表現の伝統芸で切り出し
省略値を得る。次にgetElementByNameで列挙して、一つ一つ属性を
setしてゆく。最後にファイルまたは文字列化。あたり
DTDは固定度が高いから、事前に処理しておける、
SGML 関係のソフトを参考にするとより正確なDTD解析になるでしょう
パラメータ実体の扱いなど(C or Perl のソースが予想できますが)少量ならパラメータ実体をエディタの手作業で展開して、前段の
操作で済ますとか(外部実体まで考えると気が重いが)
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2001-11-26 22:27
別の考えとして、属性無しでXMLのテキストを1度出力し
それの頭の部分にDTDのテキストを取りつけます(テキスト処理で)
そのテキストをXMLのパーサに通してから、テキストに出力する
と、属性が付いているかもしれません。
属性が多数なら試す価値アリです。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2001-11-27 10:37
普通のDOM 操作でできそうです、DTD と 空の最上位要素だけの
DOM ツリーにDTD無しで作った要素をすり替えるだけです。
<CODE>
<html><head><title>defa</title></head>
<body><script>
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc.async = false;
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.load("DefaAtt.xml");
alert(xmlDoc.xml);
//
var objNodeList = xmlDoc.getElementsByTagName("TOP");
var Elm=objNodeList.item(0);
alert(Elm.xml);
var namedNodeMap = Elm.attributes;
alert( namedNodeMap.length);
var defau = namedNodeMap.getNamedItem("DEFAU");
alert(defau.value);
// 外から持ち込んだ要素に省略値は付くか?
var xmlDoc2 = new ActiveXObject("Msxml2.DOMDocument");
xmlDoc2.async = false;
xmlDoc2.setProperty("SelectionLanguage", "XPath");
xmlDoc2.loadXML("<TOP>jjjjj</TOP>");
alert(xmlDoc2.xml);
// 恒等転記 DTD は壊れないだろうか
xmlDoc.documentElement=xmlDoc2.documentElement;
//
alert(xmlDoc.xml);
// 省略値は付いているか?
alert(xmlDoc.documentElement.attributes.getNamedItem("DEFAU").value);

</script></body></html>
<CODE>
きょうこ
会議室デビュー日: 2001/11/25
投稿数: 4
投稿日時: 2001-11-29 11:44
MMXさんの 「DTD と 空の最上位要素だけのDOM ツリーに
DTD無しで作った要素をすり替える」という方法でためしてみたところ、
メモリのオブジェクト上では属性がついているのですが、
ドキュメントをSAVEして、メモ帳等で開けてみると属性が出力されていなかったので、
取得した属性値を強制的にsetAttributeで上書きするよう、
以下のようなサブプロのcallを最後に追加してみると、うまくいきました。

Private Sub SetAttr(ObjNodes As IXMLDOMNodeList)
  Dim wNode As IXMLDOMNode
  Dim wNNMap As IXMLDOMNamedNodeMap
  Dim wElement As IXMLDOMElement

  For Each wNode In ObjNodes
    If wNode.nodeType = NODE_ELEMENT Then
      Set wElement = wNode
      Set wNNMap = wElement.Attributes
      wElement.setAttribute "DEFAU", _
        wNNMap.getNamedItem("DEFAU").nodeValue
    End If
    If wNode.hasChildNodes Then
      Call SetAttr(wNode.childNodes)
    End If
  Next

End Sub

MMXさん、どうもありがとうございました。
たいへん助かりました。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2001-11-29 15:04
最初の話には save は無かったような
DTD等が消えても良いなら、
XSLTをくぐらせるだけで省略値が付きますが。
=================================================== adddef.xsl
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
===================================================
14:46 > msxsl defaatt.xml adddef.xsl

スキルアップ/キャリアアップ(JOB@IT)