Tôi có một ứng dụng sử dụng các tệp api SAXONHE 9.2.1.1 để chuyển đổi dữ liệu XML thành văn bản thuần túy. hình thức của tôi có textbox choỨng dụng sử dụng saxonHE (9.2.1.1) api để xử lý XSLT (v2.0) đối với nhiều tệp XML
- XMLInput_FilePath
- XSLT_FilePath
- TextOutput_FilePath
Trên okButton_Click() sự kiện về hình thức của tôi, tôi đã điều sau đây:
private void okButton_Click(object sender, EventArgs e) {
FileStream xsltTransform_FileStream = File.Open(xsltTransform_FilePath.Text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
FileStream xmlInput_FileStream = File.Open(xmlInput_FilePath.Text, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
XmlTextReader modelFileXML = new XmlTextReader(xmlInput_FileStream);
modelFileXML.XmlResolver = null;
Processor processor = new Processor();
XdmNode input = processor.NewDocumentBuilder().Build(modelFileXML);
XsltTransformer xsltTransformer = processor.NewXsltCompiler().Compile(xsltTransform_FileStream).Load();
xsltTransformer.InputXmlResolver = null;
xsltTransformer.InitialContextNode = input;
Serializer serializer = new Serializer();
serializer.SetOutputFile(writeFile);
xsltTransformer.Run(serializer);
xsltTransform_FileStream.Close();
modelFileStream.Close();
}
Trong ngữ cảnh của tệp XMLInput của tôi có tham chiếu đến dữ liệu trong một tệp XML khác - xem bên dưới:
XML:
<XMLInput_File
Name="XMLInput_File">
<Subsystem Name="Subsystem">
<Requirements Name="Requirement_1">
<Rows>
<Path Text="XMLInput2_File:/XMLInput2_File/Subsystem_1/Field_1" />
</Rows>
<Rows>
<Path Text="XMLInput2_File:/XMLInput2_File/Subsystem_1/Field_2" />
</Rows>
</Requirements>
<Requirements Name="Requirement_2">
<Rows>
<Path Text="XMLInput2_File:/XMLInput2_File/Subsystem_1/Field_3" />
</Rows>
<Rows>
<Path Text="XMLInput2_File:/XMLInput2_File/Subsystem_2/Field_1" />
</Rows>
</Requirements>
</Subsystem>
</XMLInput_File>
Thuộc tính Text là nơi con đường XML file bên ngoài được lưu trữ, trong ví dụ trên, tên tập tin XML sẽ là "XMLInput2_File.xml".
XML2:
<XMLInput2_File Name="XMLInput2_File">
<Subsystem Name="Subsystem_1">
<Fields Name="Field_1">
S1_Field_One
</Fields>
<Fields Name="Field_2">
S1_Field_Two
</Fields>
<Fields Name="Field_3">
S1_Field_Three
</Fields>
</Subsystem>
<Subsystem Name="Subsystem_2">
<Fields Name="Field_1">
S2_Field_One
</Fields>
<Fields Name="Field_2">
S2_Field_Two
</Fields>
<Fields Name="Field_3">
S2_Field_Three
</Fields>
</Subsystem>
</XMLInput2_File>
XSLT:
<xsl:template match="/">
<xsl:for-each select ="//Rows/Path">
<xsl:variable name ="interfaceData" select ="@Text"/>
<xsl:variable name ="_intfModelName" select ="substring-before(@Text,':/')"/>
<xsl:variable name ="_intfFileName" select ="concat('../../OtherXMLFiles/',$_intfModelName,'.xml')"/>
<xsl:apply-templates select ="document($_intfFileName)/*[@Name=$_intfModelName]/*">
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
Tôi đang sử dụng Microsoft Visual Studion 2008 Professional Edition để thử nghiệm chuyển đổi của tôi và kịch bản trên hoạt động chính xác như mong muốn - tài liệu() tham chiếu tệp bên ngoài cụ thể hơn. Tuy nhiên, khi tôi sử dụng ứng dụng C# Winform và các cuộc gọi saxon api, tệp đầu ra của tôi chứa dữ liệu trống (các dòng trống).
Sau một vài thử nghiệm và tìm kiếm trên Internet, tôi đã đi đến kết luận rằng đường dẫn tương đối [trong XSLT] của tôi không được áp dụng như mong muốn. Có vẻ như saxon api gọi quá trình hàm document() từ vị trí của tệp transform.exe và không phải là tệp đầu vào (đó là những gì tôi muốn).
Tôi đã cố gắng thực hiện nhiều tìm kiếm trên Internet hơn về vấn đề này và tôi nhầm lẫn về vấn đề nằm trong tệp XSLT của tôi hay trong cuộc gọi saxon api trong sự kiện okButton_Click(). Hơn nữa, tôi đã đến trang web của saxon và documentation để được trợ giúp, nhưng vô ích.
tôi cập nhật XSLT theo trả lời của bạn và tôi vẫn nhận được cùng Kết quả - dữ liệu trống – Lorentz
Tôi thấy một số vấn đề khác với mẫu đã đăng của bạn, bạn đã đăng phần tử 'Rows' với phần tử con' Đường dẫn' có thuộc tính 'Văn bản' nhưng mã của bạn thực hiện' for-each select = "//Rows "' và sau đó truy cập vào '@ Text' của những phần tử' Rows', không phải của con 'Path'. Vì vậy, dựa trên các mẫu đã đăng bạn có thể muốn' for-each select = "// Rows/Path" ' –
Xin cảm ơn Martin - chính xác là bạn đã cập nhật bài viết gốc – Lorentz